欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > Redis的事务

Redis的事务

2025/4/18 11:17:09 来源:https://blog.csdn.net/wk200411/article/details/147065805  浏览:    关键词:Redis的事务

Redis的事务

  • 一.redis事务简介
    • 1.redis是否有原子性
    • 2.不具备一致性
    • 3.不具备持久性
    • 4.不涉及隔离性
  • 二.redis事务的意义
  • 三.事务的命令
    • 1.开启事务(MULTI)
    • 2.执行事务(EXEC)
    • 3.放弃当前事务(DISCARD)
    • 4.WATCH监控某个key
  • 四.WATCH实现原理

一.redis事务简介

1.redis是否有原子性

redis是否存在原子性这个仁者见仁智者见智,此处只是对其做一个简单的分析,redis的原子性和MySQL的原子性是不同的。

MySQL的原子性是把多个操作打包到一起,要么这些操作都执行成功,要么这些操作都不执行,如果执行过程中有事务操作执行失败了,事务就会进行回滚。

Redis的原子性只是将多个操作打包到一起,要么都一起执行,要么都不执行,不会管执行过程中是否成功。

这也就导致了,原子性的门槛被提高了,有些人说redis有原子性,有些人又说redis没有原子性,其实还是看大家如何理解原子性这个特点的,每个人理解的不同那么就会有不同的结论,其实都是对的(个人看法)

2.不具备一致性

redis没有约束,也没有回滚机制,事务执行过程中,如果某个修改操作出现失败,就可能引起不一致的情况。

3.不具备持久性

redis本身就是内存数据库,数据是存储在内存中的,虽然redis也有持久化操机制,但是这里的持久化机制和事务没有啥关联。

4.不涉及隔离性

redis是一个单线程模型的服务器程序,所有请求/事务都是串行执行的。

二.redis事务的意义

redis事务的主要意义就是用于打包,避免其他客户端的命令,插队查到中间。redis中实现事务,是引入了队列的,每个客户端都有一个队列。

开启事务的时候,此时客户端输入的命令,就会发给服务器并且进入这个队列中(而不是立即执行),当遇到执行事务的命令的时候,此时就会把队列中的这些任务按照顺序依次执行(在redis主线程中完成,主线程会把事务中的操作都执行完再处理其他客户端)。

三.事务的命令

1.开启事务(MULTI)

此时开启事务后,set key后的返回值不再是OK,而是QUEUED了,而且在其他redis客户端上,也查不到这几个创建的key。
在这里插入图片描述
在这里插入图片描述

2.执行事务(EXEC)

执行事务后,返回了三个OK,也就代表之前开启事务的命令都执行成功了,这三个OK是之前设置的三个key。
在这里插入图片描述
此时执行事务之后,在其他客户端上也可以看到这个数据。
在这里插入图片描述

3.放弃当前事务(DISCARD)

此时就将刚才提交的事务全部丢弃了:
在这里插入图片描述

当开启事务后,给服务器发送若干个命令,此时服务器进行重启操作,此时的事务就相当于被DISCARD了:
在这里插入图片描述

4.WATCH监控某个key

如果有两个客户端,当第一个客户端开启事务后,提交了代码,但是此时第一个客户端并没有执行事务,第二个客户端先将key设置成了其他值后,第一个客户端再执行事务,此时这个key的value值是为第一个客户端执行事务后的value值,因为第一个客户端执行事务的命令更晚。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时上述的场景就可以使用WATCH命令来监控这个key,看看key在事务的MULTI、EXEC之间和set key之后,是否被其他外部的客户端修改了。

此时exec在执行上述事务的命令时,发现key在外部的客户端中进行了修改,于是真正执行set key3 123123123的时候并没有真正的执行。
在这里插入图片描述
在这里插入图片描述

如果需要取消监视key,可以通过unwatch来进行取消,unwatch直接取消所有的key的监视

四.WATCH实现原理

redis的watch相当于是基于版本号的机制来实现的乐观锁,本质上是给exec加了个判定条件。

当两个客户端存在时,此时对第一个客户端,进行了watch key的操作,当执行了watch key的操作时,就会给key安排一个版本号,这个版本号可以理解为一个"整数",每次在修改的时候版本号会变大(所谓的变大不一定是自增,有可能直接从1变成100)

当第一个客户端watch key(必须要使用MULTI开启事务)后,此时第二个客户端也插入一个key值,而只要是针对第一个客户端中相同的key做出修改,就会引起版本号的变大,此时key的版本号就不同了。

第一个客户端又紧接着对key的值进行了修改,在通过exec命令执行事务时,会判断此时key的版本号和最初watch的时候记录的版本号是否一致。

如果此时版本号一致,说明当前设置的key在事务开启时到最终执行这个过程中,没有别的客户端修改,于是才能真正进行设置,如果不一致,说明key在其他客户端中改过了,因此就直接丢弃事务中的操作,exec返回一个nil。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词