Redis 事务

发布于:2024-06-26 ⋅ 阅读:(58) ⋅ 点赞:(0)

一、对比 MySQL 中事务的四大特征

1. 原子性

Redis 中事务的原子性是:将多个操作打包在一起执行,要么全部都执行,要么全部都不执行,则全部都执行时,可能会执行不成功,但此时不会回滚;

MySQL 中事务的原子性则为:将多个操作打包在一起执行,要么全部都执行成功,要么全部都不执行,当执行不成功时,则会回滚;

旧版本的 Redis 官网上对事务的描述为:

3c6181cb780c4e0981c4d07eff6433d7.png

但是在新版本中,第一句话被删除了:

3240f2bb7c2345c3af0aedabcb7c4e6f.png

可以看出对于事务原子性的定义是更倾向于 MySQL 中事务的原子性,即带有回滚的原子性,在这种情况下看来,Redis 中的事务是不具备原子性的; 

2. 一致性 

Redis 中的事务不具备一致性,由于 Redis 不涉及 "约束",也没有回滚机制,则在事务执行后,可能会出现数据不一致的情况;

3. 持久性

Redis 是内存数据库,数据是在内存中存储的,虽然 Redis 存在持久化机制,但是和事务无关,即 持久性是指 Redis 的持久性,而并非是 Redis 事务的持久性; 

4. 隔离性

Redis 事务不涉及隔离性,因为 Redis 是一个单线程模型的服务器程序,所有的请求 / 事务都是串行执行的;

综上所述,Redis 的事务并不具备 MySQL 事务的四大特征,Redis 事务存在的意义主要是为了 "打包",将多个操作打包为一个整体,防止其他操作穿插执行;

二、事务操作

Redis 事务本质上是在服务器上搞了一个 "事务队列";每次客户端在事务中进行一个操作,都会把命令先发给服务器,放到 "事务队列" 中;当收到执行事务命令 exec 的时候,就会把队列中的这些任务都按照顺序依次进行;

1. 开启事务 

MULTI:开启一个事务,执行成功返回 OK

aa8242d1187a48a996bc22333f70c53d.png

开启事务之后,输入的命令不会立即执行,而是进入队列中

既然不会立即执行,那如果输入错误的 redis 命令会怎么样呢?

9ca13f0cb58f4363bfb92d1dc5d9e144.png

可以看出即使不会立即执行,Redis 也会对输入的命令检测; 

2. 执行事务

EXEC:真正执行事务,并返回事务中每个操作的执行结果,执行完毕之后结束本次事务

a72f47c0e6704d3abd5fd20da8f2bdc1.png

输入 EXEC 命令之后,本次事务就执行完毕了,此时输入的操作就是非事务的操作执行的;

e5c00a94792d497c89fbc65ba5cf4449.png

3. 放弃当前事务

DISCARD,丢弃当前事务之后,事务中的操作都不会执行

a7973f01448c49a4b3f1db9bcf3b8e15.png

4. 监控某个 key,在事务执行之前是否发生了改变

WATCH 

若存在两个客户端,一个客户端(ubuntu)开启了事务之后,先执行了 set key 111,然后另一个客户端(ubuntu2)没有开启事务,执行了 set key 222,然后客户端(ubuntu)执行了事务,此时get key 得到的结果是 111,因为客户端(ubuntu)虽然先输入 set key 命令,但是是后执行事务的,也就是后执行 set key 命令的;如下图所示

dd436d91c63242d2bccc7f0a3b2997ab.png

watch 就可以监控 key,在客户端(ubuntu)开启事务并 set key 之后,key 是否再次发生改变,如果该 key 发生改变了,再执行事务,则事务会执行失败;

 29dee43168644c788d7ddc2ff19a094c.png

 

 


网站公告

今日签到

点亮在社区的每一天
去签到