![e3aa23f9341c8c0a3c2e536c23bfd13b.png](https://i-blog.csdnimg.cn/blog_migrate/76b6add65d8cf78b1e3689f135627059.jpeg)
事物介绍
有时候我们需要redis连续发送多个命令不能被中断,此时就需要使用到redis特殊的命令功能;redis有 5个命令可以实现多个命令执行操作,他们分别是WATCH, MULTI(开启事物), EXEC(执行命令), UNWATCH 和 DISCARD(丢弃事物);
Redis事物需要使用到MULTI和 EXEC命令,其和关系型数据库的回滚事物不同;redis会一个接着一个执行保含在MULTI和 EXEC 命令范围内的命令;只有执行完redis事物的命令才会执行其它客户端命令;我们已经可以理解首先执行的是MULTI命令,其次是我们想要在事物里面执行的命令,最后是EXEC命令执行完队列中的命令代表结束。Redis在执行事物的时候,其实会开启队列,将我们要执行的事物命令放入队列中,所以命令必须一个执行完毕才能执行下一个命令;
事物示例
首先执行multi 命令
127.0.0.1:6379> multi # 开启事物
OK
127.0.0.1:6379>
其次输入我们的命令,放入队列中
127.0.0.1:6379> set z1 666
QUEUED
127.0.0.1:6379> set z2 555
QUEUED
127.0.0.1:6379> set z3 222
QUEUED
127.0.0.1:6379>
最后EXEC命令执行队列中的命令
127.0.0.1:6379> exec # 执行命令
1) OK
2) OK
3) OK
127.0.0.1:6379>
事物原子性
事物的原子性是指事物要么全部成功,要么全部失败;即出现异常的时候会事物会回滚;但redis的事物并不是原子性,如下示例中可以看出出现异常后,事物照样运行命令;
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 000
QUEUED
127.0.0.1:6379> set k2 66 66 66
QUEUED
127.0.0.1:6379> set k3 000
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR syntax error
3) OK
127.0.0.1:6379> keys k*
1) "k3"
2) "k1"
127.0.0.1:6379>
discard丢弃
丢弃是指丢弃队列中所有的命令,这样multi命令就相当于未发生过;discard 命令 需在exec命令之前执行;
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set s1 111
QUEUED
127.0.0.1:6379> set s2 222
QUEUED
127.0.0.1:6379> discard # 丢弃
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
127.0.0.1:6379>
watch监控
我们都知道 redis 的 分布式锁是一个悲观锁,提供了很好的并发解决方案;但更好的方式是使用watch命令来监控一个值是否变化,如果值发生改变,exec执行的命令将会返回null,故watch 命令是一个乐观锁的解决方案;
127.0.0.1:6379> set s3 ooo
OK
127.0.0.1:6379> watch s3
OK
127.0.0.1:6379> set s3 555 # 修改了变量
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set s3 222
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>
Redis 不可以在 multi 和 exec 之间执行 watch 指令,必须在 multi 之前执行,否则报错;
unwacth 命令是撤销对一个变量的监控;