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;反之,未被修改,进行真正执行。

相关推荐
小陈工2 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
科技小花6 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸6 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain6 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希7 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神7 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员7 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java7 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿7 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴7 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存