这是我参与「第三届青训营 -后端场」笔记创作活动的第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)正常执行
2)全体连坐
定义事务的过程中,命令格式输入错误怎么办?
-
语法错误
- 指命令书写格式有误 例如执行了一条不存在的指令
-
处理结果
- 如果定义的事务中所包含的命令存在语法错误,整体事务中所有命令均不会执行。包括那些语法正确的命令
3)放弃事务
4)冤头债主
定义事务的过程中,命令执行出现错误怎么办?
-
运行错误
- 指命令格式正确,但是无法正确的执行。例如对list进行incr操作
-
处理结果
-
能够正确运行的命令会执行,运行错误的命令不会被执行
-
注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现回滚。
监控锁
-
对 key 添加监视锁,在执行 exec 前如果key发生了变化,终止事务执行
watch key1, key2....
-
取消对所有key的监视
unwatch
取消监控后,事务正常执行。
总结
3 阶段
- 开启:以MULTI开始一个事务
- 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
- 执行:由EXEC命令触发事务
3 特性
- 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。
- 不保证原子性:redis 同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。