Redis学习笔记—Redis的事务
1. Redis事务(弱事务)和Mysql事务对比
-
Atomicity(原子性)
:构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。Redis
:一个队列中的命令执行或不执行 -
Consistency(一致性)
:数据库在事务执行前后状态都必须是稳定的或者是一致的。Redis
:集群中不能保证时时的一致性,只能是最终一致性(弱一致性)
-
Isolation(隔离性)
:事务之间不会相互影响。Redis
:命令是顺序执行的,在一个事务中,有可能被执行其他客户端的命令的 -
Durability(持久性)
:事务执行成功后必须全部写入磁盘。Redis
:有持久化但不保证数据的完整性
2. Redis事务(更多应用于实现乐观锁)
- Redis的事务是通过multi、exec、discard和watch这四个命令来完成的。
- Redis的单个命令都是原子性的,所以这里需要确保事务性的对象是命令集合。
- Redis将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行
- Redis不支持回滚操作
3. 事务命令
-
multi
:用于标记事务块的开始,Redis会将后续的命令逐个放入队列中,然后使用exec原子化地执行这个命令队列multi 命令标记事务后,写的get/set命令 不会马上执行,都会被放到
CommondQueue(命令队列)
中 -
exec
:执行命令队列,把CommondQueue(命令队列)
中的命令全部放到服务器(RedisServer)
中去执行 -
discard
:清除命令队列 -
watch
:监视key -
unwatch
:清除监视key
4. 事务的机制
4-1 事务的执行
- 事务开始
- 在
RedisClient
中,有属性flags
,用来表示是否在事务中flags=REDIS_MULTI
- 在
- 命令入队
RedisClient
将命令存放在事务队列中(EXEC,DISCARD,WATCH,MULTI除外)
- 事务队列
multiCmd *commands
用于存放命令
- 执行事务
RedisClient
向服务器端发送exec
命令,RedisServer
会遍历事务队列,执行队列中的命令,最后将执行的结果一次性返回给客户端。
- 如果某条命令在入队过程中发生错误,
redisClient
将flags
置为REDIS_DIRTY_EXEC
,EXEC
命令将会失败返回。
4-2 Watch的执行
使用WATCH命令监视数据库键
:redisDb
有一个watched_keys
字典,key
是某个被监视的数据的key
,值是一个链表,记录了所有监视这个数据的客户端。监视机制的触发
:当修改数据后,监视这个数据的客户端的flags
置为REDIS_DIRTY_CAS
事务执行
:RedisClient
向服务器端发送exec
命令,服务器判断RedisClient
的flags
,如果为REDIS_DIRTY_CAS
,则清空事务队列。
5. Redis的弱事务性
Redis语法错误
:整个事务的命令在队列里都清除,flags=REDIS_DIRTY_EXEC
Redis运行错误
:在队列里正确的命令可以执行 (弱事务性)- 弱事务性 :
- 在队列里正确的命令可以执行 (非原子操作)
- 不支持回滚
- 弱事务性 :
Redis不支持事务回滚
(为什么呢)- 大多数事务失败是因为语法错误或者类型错误,这两种错误,在开发阶段都是可以预见的
- Redis为了性能方面就忽略了事务回滚。 (回滚记录历史版本)