Redis笔记(三):事务
什么是Redis事务
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
Redis事务相关命令和使用
MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
EXEC:执行事务中的所有操作命令。
DISCARD:取消事务,放弃执行事务块中的所有命令。
WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
UNWATCH:取消WATCH对所有key的监视。
如何理解Redis与事务的ACID?
- 原子性atomicity
Redis事务在编译错误时回滚,运行时错误跳过。很多文章由此说Redis事务违背原子性的;而官方文档认为是遵从原子性的。
Redis官方文档给的理解是,Redis的事务是原子性的:所有的命令,要么全部执行,要么全部不执行。而不是完全成功。
- 一致性consistency
redis事务可以保证命令失败的情况下得以回滚,数据能恢复到没有执行之前的样子,是保证一致性的,除非redis进程意外终结。
- 隔离性Isolation
redis事务是严格遵守隔离性的,原因是redis是单进程单线程模式(v6.0之前),可以保证命令执行过程中不会被其他客户端命令打断。
但是,Redis不像其它结构化数据库有隔离级别这种设计。
- 持久性Durability
redis事务是不保证持久性的,这是因为redis持久化策略中不管是RDB还是AOF都是异步执行的,不保证持久性是出于对性能的考虑。
CAS操作实现乐观锁
check-and-set (CAS):被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回nil-reply来表示事务已经失败。
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
Redis事务执行步骤
通过上文命令执行,很显然Redis事务执行是三个阶段:
- 开启:以MULTI开始一个事务
- 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
- 执行:由EXEC命令触发事务
当一个客户端切换到事务状态之后, 服务器会根据这个客户端发来的不同命令执行不同的操作:
- 如果客户端发送的命令为 EXEC 、 DISCARD 、 WATCH 、 MULTI 四个命令的其中一个, 那么服务器立即执行这个命令。
- 与此相反, 如果客户端发送的命令是 EXEC 、 DISCARD 、 WATCH 、 MULTI 四个命令以外的其他命令, 那么服务器并不立即执行这个命令, 而是将这个命令放入一个事务队列里面, 然后向客户端返回 QUEUED 回复。