欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Redis:事务 - 事务操作

最编程 2024-10-12 18:29:12
...

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时,会记录当前的版本号。在事务提交时,检测当前的版本号是否与之前的版本号相同,如果相同那么提交成功,如果版本号不同,说明有别的用户修改了数据,导致版本号修改,事务就直接被丢弃了。