Redis进阶(二)—— Redis 事务

2. Redis事务

2.1 Redis 事务 和 MySQL 事务区别

Redis 事务 和 MySQL 事务概念上类似,都是指 把一系列操作在一起执行,不允许中间插入。

Redis 事务特点:

  • 弱原子性 或 无原子性:redis 没有回滚机制,只是批量一起执行,里面有失败就是失败了。
  • 不保证一致性:redis 不涉及约束,没有回滚。前后结果不都合理有效,可能有非法中间态。
  • 不需要保隔离性:没有隔离级别,因为不会并发执行事务(redis 单线程处理请求)
  • 不需持久性:存在内存里,是否开启持久,是配置的问题,和事务无关。

Redis 事务本质上,是客户端上有一个 "事务队列",每次客户端开启事务,命令先存到队列中,服务器收到 exec 命令,按顺序执行队列中的操作。

2.2 使用场景示例

Redis 事务,主要就是避免其他客户端命令插队执行,将操作打包执行。

如:秒杀活动

一个经典写法:

bash 复制代码
//获取仓库剩余商品个数
if(个数 > 0) {
	下单成功
	个数减一;	
}

如果不加锁,就存在 "线程安全" 问题,在 Redis 使用事务来解决。

redis 原生命令中不支持类似上面的条件判断,但是 redis 支持 lua 脚本,通过 lua 脚本就可以实现,且和 redis 事务一样是打包批量执行。

2.3 使用事务

redis 中通过 MULTI 开启事务,EXEC 执行事务, DISCARD 放弃当前事务。

开启事务后,先放入事务队列,此时没有执行事务,在其他客户端上是看不到这几个键的。

执行 EXEC

这时,这几个键才真正放入 redis 中,同时在 新窗口中也可查询到。

如果,事务结束前,出现了服务器重启等情况,就相当于是 DISCARD

下面讲一种情况,key 的值初始为 111,客户端1 开启了事务,并将 key 设为 222,但是在客1事务执行前,客户端2 将 key 设为了 333。虽然,从顺序上看,客1 是先设置的 key 为 222,但实际 set key 222 执行的晚,结果为 222。

为此,redis 中有 WATCH 命令可以监视某个或某些 key 在事务执行前是否发生了变化。

客户端1 设置 key1 为 222,但未执行。客户端2 设置 key1 为 .

666。

客户端1 执行事务

由于 key1 在事务执行前发生了改变,所以返回了 nil 没有执行。

2.4 WATCH 的实现原理

watch 的实现,类似于 "乐观锁"。

乐观锁 是一类锁的特质,即加锁前,预期锁冲突几率比较低,先不加锁。冲突真正发生再加锁。

想要看 乐观锁 的更细节讲述,可看此文章:多线程进阶

redis 的 watch 基于版本号这样的机制,来实现了 "乐观锁"。

watch key 的时候,会给 key 安排一个 版本号,给 exec 加了一个判定条件,每次修改 key 都会引起版本号变化,当执行 EXEC 时,就会进行判定,版本号不一致说明 key 被修改过,就丢弃该操作,返回 nil;反之,未被修改,进行真正执行。

相关推荐
衫水4 小时前
ubuntu系统如何检查和安装以及运行redis
redis·ubuntu·bootstrap
正在走向自律5 小时前
金仓数据库KingbaseES中级语法详解与实践指南
数据库·oracle·kingbasees·金仓数据库·信创改造
Gofarlic_oms15 小时前
Windchill用户登录与模块访问失败问题排查与许可证诊断
大数据·运维·网络·数据库·人工智能
我是小疯子665 小时前
Python变量赋值陷阱:浅拷贝VS深拷贝
java·服务器·数据库
Zoey的笔记本6 小时前
2026告别僵化工作流:支持自定义字段的看板工具选型与部署指南
大数据·前端·数据库
静听山水6 小时前
docker安装starrocks
数据库
学编程的小程6 小时前
从“兼容”到“超越”:金仓KESBSON引擎如何借多模融合改写文档数据库规则
数据库
千层冷面6 小时前
数据库分库分表
java·数据库·mysql·oracle
DBA小马哥7 小时前
金仓数据库引领国产化替代新范式:构建高效、安全的文档型数据库迁移解决方案
数据库·安全·mongodb·dba·迁移学习
企业对冲系统官7 小时前
基差风险管理系统日志分析功能的架构与实现
大数据·网络·数据库·算法·github·动态规划