MULTI
,EXEC
,DISCARD
和WATCH
是事务的基础组成,事务允许一次性执行一组命令,Redis事务可以保证:
- 在事务中的命令是串行的且是按照先后顺序的。事务执行过程中是不会被中断的。
- Redis事务是原子的。触发整个事务执行的命令
EXEC
,如果客户端在执行这个命令前就宕机了,事务是不会被执行的。事务可能会被Redis的突然宕机而丢失部分操作。Redis如果重启后会报错,需要手动通过redis-check-aof工具修复。
另外,Redis使用类似于乐观锁CAS的方式,来防止写丢失
错误发生
- 在未执行
EXEC
或DISCARD
前,某条命令报错(命令不对) - 执行了EXEC,某条命令报错(incr 用在string类型上)
结论:
对于第1种情况:事务直接结束
事务特性小结
- 排队时报错
- 可以继续添加命令进队列
- 执行exec后,自动discard
- 所有命令都不成功
- 执行时出错
- 该成功的还是成功了
为什么不回滚
- 像incr a(字符串) 这种错误在实际的生产中是不会出现的,因为开发者清楚自己要干什么。但是命令错误还是有可能出现的。所以命令错误时给你个回滚的机会
- Redis说我快,回滚会影响我的速度(女朋友只会影响我干饭的速度)
保证事务的隔离性
前面说过如果事务执行了EXEC后,它是不会被中断的,且不会被其他命令插入的。但是在`EXEC`之前发送的一些数据变化也需要一个控制。<br />因此Redis为我们提供了一个`WATCH` 命令,用于监测某个key的值,在`MULTI`执行前,watch某个key,如果在事务exec前,key值被其他事务修改。则本事务直接失败。<br />要点:
- 开启事务前使用watch(一定是同一客户端)
- 事务使用exec和discard后是无需手动unwatch的