Redis:事务 - 事务操作
MULTI & EXEC
-
multi
:开启事务 -
exec
:提交事务
示例:
开启事务后,不论输入什么指令,都返回QUEUE
,此时会在客户端维护一个队列,将所有指令入队列。最后执行exec
提交事务,所有的指令再同时返回。
DISCARD
-
discard
:取消事务
示例:
开启事务后,输入两个值,再通过discard
取消事务,最后查询key1
,发现插入失败,因为这个请求没有提交给客户端,而是直接被取消了。
另外的,如果在事务执行的过程中,Redis
崩溃,恢复后效果和discard
一样,就是事务内的操作都取消了。
WATCH
现有以下场景:
序号 | 客户端1 | 客户端2 |
---|---|---|
1 | multi |
|
2 | set key 111 |
|
3 | set key 222 |
|
4 | exec |
|
5 | get key |
最后客户端get key
返回值是多少?
这是一个很常见的事务问题,虽然客户端1
执行set key
更早,但是它提交事务更晚,最终客户端
的结果其实是111
。
在事务执行过程中,客户端1
无法感知外部的变化,导致客户端2
拿不到自己想要的数据,被其他事务覆盖了。
-
watch
:让事务可以监听外部的变化,如果监听的数据被外部改变,操作失效
语法:
watch key [key ...]
示例:
左侧的终端,在执行事务前开启了watch key1
,开启事务后set key1 111
。在事务提交前,右侧终端修改了key1 222
,随后左侧终端提交事务时,返回了nil
表示事务操作无效。
因为watch
监听到了key1
被外部修改,此时自己的事务提交可能会影响其它客户端,于是取消该操作。
如果想要取消watch
,可以使用unwatch
指令:
unwatch
这个指令没有参数,一次性取消所有key
的监听。
watch
使用了一种版本号的机制,每个数据都有一个版本号,每次修改key
的值时,都会修改其版本号。在watch key
时,会记录当前的版本号。在事务提交时,检测当前的版本号是否与之前的版本号相同,如果相同那么提交成功,如果版本号不同,说明有别的用户修改了数据,导致版本号修改,事务就直接被丢弃了。
上一篇: XML XSLT:转换和呈现数据的力量
下一篇: Linux 常用命令-9.mv 命令
推荐阅读