【Redis存储】redis事务

Redis 的事务和 MySQL 的事务概念上是类似的,都是一组命令的批量执行机制,能够将多个命令打包成一个 "原子操作单元",即要么所有命令都被执行,要么所有命令都不执行。

Redis事务与MySQL事务特性不一样。

  • redis没有 "回滚机制",只能做到这些操作 "批量执行",不能做到 "⼀个失败就恢复到初始状态"。
  • redis没有隔离级别,因为不会并发执行事务(redis 单线程处理请求)

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

Redis 事务通过 5 个核心命令实现,按执行流程分为 "开启→入队→执行/放弃" 三个阶段。

redis事务没有隔离级别,那么在执行事务时这里就会出现问题,如下:

# 客户端1 先执行

127.0.0.1:6379> MULTI

OK

127.0.0.1:6379> set key 100

QUEUED

# 客户端2 再执行

127.0.0.1:6379> set key 200

OK

# 客户端1 最后执行

127.0.0.1:6379> EXEC

1) OK

127.0.0.1:6379> get key

"100"

从输入命令的时间看,是客户端1 先执行的 set key 100,客户端2 后执行的 set key 200,但是从实际的执行时间看,是客户端2 先执行的,客户端1 后执行的。

redis中,watch 命令就是可以解决这个问题的。

watch 在该客户端上监控一组具体的 key。当开启事务的时候,如果对 watch 的 key 进行修改,就会记录当前 key 的 "版本号"(版本号是个简单的整数,每次修改都会使版本变大。服务器来维护每个 key 的版本号情况),在真正提交事务的时候,如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号,就会让事务执行失败(事务中的所有操作都不执行)。

# 客户端1

127.0.0.1:6379> watch k1 # 开始监控 k1

OK

127.0.0.1:6379> MULTI

OK

127.0.0.1:6379> set k1 100 # 进行修改,从服务器获取 k1 的版本号是0,记录 k1 的版本号(还没真修改呢, 版本号不变)

QUEUED

127.0.0.1:6379> set k2 1000

QUEUED

# 客户端2再执行

127.0.0.1:6379> set k1 200 # 修改成功,使服务器端的 k1 的版本号 0 -> 1

OK

# 客户端1再执行

127.0.0.1:6379> EXEC # 此时客户端的 k1 的版本号是0,服务器上的版本号是1

(nil)

127.0.0.1:6379> get k1

"200"

127.0.0.1:6379> get k2

(nil)

UNWATCH可以取消对 key 的监控,相当于 WATCH 的逆操作,此处不做演示。

相关推荐
广州浮点FLOATLIC11 分钟前
Mentor Graphics浮动许可证管理为什么一到流片节点就失控
java·大数据·数据库·许可证管理·cad 许可证优化
小王C语言40 分钟前
MySQL 库的操作:字符集和校验规则、数据库的增删查改、备份和还原
数据库·mysql
小王C语言1 小时前
MySQL 数据类型:数值类型、字符串类型、日期和时间类型、enum 和 set、find_in_set 查询
android·数据库·mysql
MC皮蛋侠客1 小时前
Redis 系列(六):过期、内存淘汰与内存优化——让 Redis 活得更久
数据库·redis·bootstrap
杜子不疼.2 小时前
模型效果不好时,我现在会先看数据集
数据库
夜雪一千2 小时前
MySQL的事务是什么?原理、ACID、隔离级别与实战详解
数据库·mysql
会编程的土豆2 小时前
从「锁」到「时间」:后端里几个容易混的概念
java·开发语言·数据库·goland
上下求索,莫负韶华2 小时前
笔记-数据库事务和java事务和切面
java·数据库·笔记
黄华SJ520it2 小时前
顶俏洗衣液模式制度开发介绍:S2B2C社交分销+多门店核销系统全解析
前端·数据库·小程序·零售·系统开发
大黄说说3 小时前
Android 本地存储深度对比:SharedPreferences、MMKV、Room 数据库怎么选?
android·数据库