快速了解 Redis 事务

1.相关指令

Redis 事务本质上是在服务器上搞了⼀个"事务队列"。每次客⼾端在事务中进⾏⼀个操作,都会把命令先发给服务器,放到"事务队列"中(但是并不会⽴即执⾏)⽽是会在真正收到EXEC命令之后,才真正执⾏队列中的所有操作。

  1. multi
  • 开启事务
java 复制代码
multi
  1. exec
  • 执行事务
java 复制代码
exec
  1. discard
java 复制代码
discard

2.Redis 事务的特性

Redis 的事务与 MySQL 事务有很大的区别。

  1. 不保证原子性:Redis 没有"回滚机制",只能做到这些操作"批量执行"。不能做到"⼀个失败就恢复到初始状态"。
  • Redis 初始时没有数据
  1. 不需要隔离性:事务中的所有命令都会按顺序执行(注意是执行,要 exec 后),不会被其他客户端的命令打断(Redis 是单线程执行请求的)。

  2. 不需要持久性:Redis 是保存在内存的。是否开启持久化要看配置,和事务⽆关。

  3. 不保证⼀致性:MySQL 的⼀致性体现的是运⾏事务前运⾏后,结果都是合理有效的,不会出现中间⾮法状态。而 Redis 事务,有可能出现数据不一致的情况。

  • 客户端1:
java 复制代码
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key1 200
QUEUED
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key1 100
OK
  • 客户端1:
java 复制代码
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key1 200
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
127.0.0.1:6379> 
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key1 100
OK
127.0.0.1:6379> get key1
"200"
127.0.0.1:6379> 

可以看到,在没有提交事务前,如果有其它客户端修改事务中相关的数据,可能让造成其它客户端的更新丢失了。比如上面案例的客户端2,如何解决呢?可以通过搭配 watch 指令来完成。

3.watch 指令

  1. 当开启事务的时候,如果对 watch 的 key 进⾏修改,就会记录当前 key 的"版本号"。(版本号是个简单的整数,每次修改都会使版本变⼤)
  2. 在真正提交事务的时候,如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号,就会让对应的 key 执⾏失败,但是没有被 watch 监控的 key 还是会被执行。
  • 客户端1:
java 复制代码
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key 100
QUEUED
127.0.0.1:6379(TX)> set key1 200
QUEUED
127.0.0.1:6379(TX)> 
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key 20
OK
127.0.0.1:6379> 
  • 客户端1:
java 复制代码
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key 100
QUEUED
127.0.0.1:6379(TX)> set key1 200
QUEUED
127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> get key
"20"
127.0.0.1:6379> get key1
"200"
127.0.0.1:6379> 
  • 客户端2:
java 复制代码
127.0.0.1:6379> set key 20
OK
127.0.0.1:6379> get key
"20"
127.0.0.1:6379>

注意到,并没有停止执行事务。没有被 watch 监控的 key 还是会被执行。

相关推荐
风一样的树懒34 分钟前
死信队列:你在正确使用么?
后端
RoyLin37 分钟前
TypeScript设计模式:门面模式
前端·后端·typescript
JavaGuide40 分钟前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
weiwenhao1 小时前
关于 nature 编程语言
人工智能·后端·开源
薛定谔的算法1 小时前
phoneGPT:构建专业领域的检索增强型智能问答系统
前端·数据库·后端
RoyLin1 小时前
TypeScript设计模式:责任链模式
前端·后端·typescript
RoyLin1 小时前
TypeScript设计模式:装饰器模式
前端·后端·typescript
Java中文社群1 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心2 小时前
从零开始学Flink:数据源
java·大数据·后端·flink
掘金一周2 小时前
Flutter Riverpod 3.0 发布,大规模重构下的全新状态管理框架 | 掘金一周 9.18
前端·人工智能·后端