MULTI,EXEC,DISCARDWATCH是事务的基础组成,事务允许一次性执行一组命令,Redis事务可以保证:

  1. 在事务中的命令是串行的且是按照先后顺序的。事务执行过程中是不会被中断的。
  2. Redis事务是原子的。触发整个事务执行的命令EXEC,如果客户端在执行这个命令前就宕机了,事务是不会被执行的。事务可能会被Redis的突然宕机而丢失部分操作。Redis如果重启后会报错,需要手动通过redis-check-aof工具修复。

另外,Redis使用类似于乐观锁CAS的方式,来防止写丢失

image.png

错误发生

  1. 在未执行EXECDISCARD前,某条命令报错(命令不对)
  2. 执行了EXEC,某条命令报错(incr 用在string类型上)

结论:
对于第1种情况:事务直接结束
image.png

对于第2种情况:成功的就成功了,不成功就不成功,不会回滚
image.png

事务特性小结

  1. 排队时报错

image.png

  • 可以继续添加命令进队列
  • 执行exec后,自动discard
  • 所有命令都不成功
    1. 执行时出错

image.png

  • 该成功的还是成功了

为什么不回滚

  1. 像incr a(字符串) 这种错误在实际的生产中是不会出现的,因为开发者清楚自己要干什么。但是命令错误还是有可能出现的。所以命令错误时给你个回滚的机会
  2. Redis说我快,回滚会影响我的速度(女朋友只会影响我干饭的速度)

保证事务的隔离性

  1. 前面说过如果事务执行了EXEC后,它是不会被中断的,且不会被其他命令插入的。但是在`EXEC`之前发送的一些数据变化也需要一个控制。<br />因此Redis为我们提供了一个`WATCH` 命令,用于监测某个key的值,在`MULTI`执行前,watch某个key,如果在事务exec前,key值被其他事务修改。则本事务直接失败。<br />要点:
  • 开启事务前使用watch(一定是同一客户端)
  • 事务使用exec和discard后是无需手动unwatch的

image.png

最后

Redis官方说事务后面可能直接废弃,我们推荐使用脚本。

参考文章