Redis事务 | 青训营笔记

149 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记。

最近在写青训营项目的时候用到了redis,利用set来实现点赞之类的功能,涉及到了执行多条redis命令的情况,redis是支持事务的,但与MySQL的事务不太一样,这里做一下简单记录。

Redis事务

1、Redis事务的定义

redis 事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序依次执行,中间不会被打断或者干扰。

2、事务的基本操作

  • 开启事务

      multi
    

    作设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中

  • 取消事务

    discard
    

    终止当前事务的定义,发生在multi之后,exec之前

  • 执行事务

    exec
    

    设定事务的结束位置,同时执行事务。与multi成对出现,成对使用

  • 监控key

      watch key
    

    通过 WATCH 命令在事务执行之前监控了多个 Keys,倘若在 WATCH 之后有任何 Key 的值发生了变化EXEC 命令执行的事务都将被放弃,同时返回 Nullmulti-bulk 应答以通知调用者事务执行失败。

3、事务操作的基本流程

4、事务操作的注意事项

1)正常执行

QQ截图20201201205556.png

2)全体连坐

定义事务的过程中,命令格式输入错误怎么办?

  • 语法错误

    • 指命令书写格式有误 例如执行了一条不存在的指令
  • 处理结果

    • 如果定义的事务中所包含的命令存在语法错误,整体事务中所有命令均不会执行。包括那些语法正确的命令

QQ截图20201201205230.png

3)放弃事务

QQ截图20201201205811.png

4)冤头债主

定义事务的过程中,命令执行出现错误怎么办?

  • 运行错误

    • 指命令格式正确,但是无法正确的执行。例如对list进行incr操作
  • 处理结果

    • 能够正确运行的命令会执行,运行错误的命令不会被执行

QQ截图20201201205346.png

注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现回滚。

监控锁

  • 对 key 添加监视锁,在执行 exec 前如果key发生了变化,终止事务执行

      watch key1, key2....
    

QQ截图20201201210114.png

QQ截图20201201210351.png

  • 取消对所有key的监视

    unwatch
    

QQ截图20201201210534.png

取消监控后,事务正常执行。

总结

3 阶段

  • 开启:以MULTI开始一个事务
  • 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  • 执行:由EXEC命令触发事务

3 特性

  • 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。
  • 不保证原子性:redis 同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。