Redis之事务
事务
- mysql的事务
mysql的事务满足ACID:原子性、一致性、隔离性和持久性。
- redis的事务
事务是指一个完整的动作,要么全部执行,要么什么也没有做。
Redis 事务不是严格意义上的事务,只是用于帮助用户在一个步骤中执行多个命令。
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
Redis 事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
redis将多个命令打包成一个,然后一次性按照顺序执行命令;
redis具有一次性、顺序性、排他性
Redis事务没有没有隔离级别的概念
所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
事务的阶段
一个事务从开始到执行会经历以下三个阶段
- 开始事务。
- 命令入队。
- 执行事务。
事务的命令
MULTI、EXEC、DISCARD、WATCH 这四个指令构成了 redis 事务处理的基础。
- MULTI 用来启动一个事务;
- EXEC 用来执行一个事务;一次性将事务中的所有操作执行完成后返回给客户端;
- DISCARD 用来取消一个事务;
- WATCH 乐观锁,用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行。在EXEC命令执行之前,用于监视指定数量键;如果监视中的某任意键数据被修改,则服务器拒绝执行事务;
案例
- MULTI
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379(TX)> set k1 v1 #命令入队
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get v2
QUEUED
127.0.0.1:6379(TX)> EXEC #执行事务,按照入队的顺序执行
1) OK
2) OK
3) OK
4) (nil)
- DISCARD
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)>
127.0.0.1:6379(TX)>
127.0.0.1:6379(TX)>
127.0.0.1:6379(TX)>
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> DISCARD #取消事务
OK
127.0.0.1:6379>
127.0.0.1:6379> get k4
(nil)
- 编译型异常(代码有问题!命令有错!)
事务中所有的命令都不会被执行!
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> GETSET k3 #错误命令
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> set k5 v5
QUEUED
127.0.0.1:6379(TX)> EXEC #执行事务报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k5 #事务中所有的命令都没有执行
(nil)
127.0.0.1:6379> get k1
(nil)
- 运行时异常
如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常!
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> INCR k1 #给字符串自增1,不能给字符串自增
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> get k3
QUEUED
127.0.0.1:6379(TX)> EXEC
1) (error) ERR value is not an integer or out of range #第一条命令执行报错了,但是依旧执行了
2) OK
3) OK
4) "v3"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)