redis watch multi exec 关系

时间:2023-03-13 13:35:14

EXEC

执行所有事务块内的命令。

假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么EXEC 命令只在这个(或这些) key 没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。

返回值:
事务块内所有命令的返回值,按命令执行的先后顺序排列。
当操作被打断时,返回空值 nil 。

# 监视 key ,且事务成功执行
127.0.0.1:6379> get key
"111"
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key 222
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get key
"222"
127.0.0.1:6379> # 监视 key ,且事务被打断 127.0.0.1:6379> set key 222
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get key
"222"
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> set key 333
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key 444
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get key
"333"
------------------
在同一个客户端下 只要在watch之后,multi执行之前改变key的值,则将以改变后的值为当前的key值,之后事务中执行关于改变key值的操作将不再生效.
在不同客户端下,例如在a客户端执行watch key 然后执行multi .这时在b客户端下重新set key 值,再回到a客户端,也重新设置另一个set key 值,这时exec后将返回为空值,最终key值为b客户端下设定的值.
理论上来说将会以a客户端在事务中最后设置的值为最终值,但是a客户端会认为b客户端在multi之前执行的值,此后a客户端执行便返回为空.