当前位置: 首页 > news >正文

Redis事务失败的处理机制与处理方案

一、Redis 事务执行流程全景图

二、事务执行失败的三大类型及处理机制

1. 语法错误(编译时错误)

特征:命令在入队时立即检测到错误

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET key1 value1
QUEUED
127.0.0.1:6379> INCRBY key1 100  # 对非数字值操作
(error) ERR value is not an integer or out of range  # 立即报错
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
  •  ✅ 处理机制事务整体回滚,所有命令不执行

2. 运行时错误(执行时错误)

特征:命令语法正确但执行时违反约束

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET balance "abc"  # 字符串值
QUEUED
127.0.0.1:6379> INCRBY balance -100  # 对字符串执行减法
QUEUED
127.0.0.1:6379> EXEC
1) OK  # 第一条命令成功
2) (error) ERR value is not an integer or out of range  # 第二条失败
  •  ✅ 处理机制失败命令后的操作继续执行,无自动回滚

3. 资源限制错误

特征:超出系统限制导致的失败

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET small_key "val"
QUEUED
127.0.0.1:6379> SET big_key "巨型值..."  # 超过maxmemory
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) OOM command not allowed when used memory > 'maxmemory'
  • ✅ 处理机制错误命令失败,后续命令正常执行 

三、事务原子性的本质剖析

Redis 事务的原子性 ≠ 传统数据库原子性:

核心结论
Redis 仅保证 命令入队的原子性 和 执行的隔离性,不保证操作结果的原子性

四、生产环境事务失败处理方案

方案1:WATCH 命令实现乐观锁 

Jedis jedis = new Jedis("localhost");
String key = "balance:1001";while (true) {jedis.watch(key);int balance = Integer.parseInt(jedis.get(key));if (balance < 6000) break; // 检查条件Transaction tx = jedis.multi();tx.set(key, String.valueOf(balance - 6000));List<Object> results = tx.exec();if (results != null) { break; // 执行成功}// 如果失败则重试
}
jedis.unwatch();

 方案2:Lua 脚本(原子操作)

-- 原子转账脚本
local from_acc = KEYS[1]
local to_acc = KEYS[2]
local amount = tonumber(ARGV[1])local from_balance = tonumber(redis.call('GET', from_acc))
if from_balance < amount thenreturn {err = "Insufficient funds"}
endredis.call('DECRBY', from_acc, amount)
redis.call('INCRBY', to_acc, amount)return {status = "SUCCESS"}
http://www.lryc.cn/news/585727.html

相关文章:

  • 日历插件-FullCalendar的详细使用
  • C++:非类型模板参数,模板特化以及模板的分离编译
  • 【整数大求余草稿】2022-3-7
  • 进制转换原理与实现详解
  • Qt中QGraphicsView类应用解析:构建高效2D图形界面的核心技术
  • vue table 自定义处理 key 作为 表头
  • AUTOSAR进阶图解==>AUTOSAR_SWS_IOHardwareAbstraction
  • [精选]如何解决pip安装报错ModuleNotFoundError: No module named ‘subprocess’问题
  • Matlab裁剪降水数据:1km掩膜制作实战
  • C++STL-list
  • 这个方法的目的是检查一个给定的项目ID(projectId)是否在当前数据库中被使用(搜索全库)
  • 四、神经网络——正则化方法
  • VLM-R1 + GRPO 算法完整复现全过程日志
  • Linux修炼:权限
  • SpringCloud【OpenFeign】
  • 学习日记-spring-day46-7.11
  • 伺服驱动控制CANopen协议
  • 网络编程(基本概念)
  • 【C++篇】二叉树进阶(上篇):二叉搜索树
  • TCP详解——流量控制、滑动窗口
  • mysql的性能优化:组提交、数据页复用、全表扫描优化、刷脏页
  • 【JMeter】调试方法
  • 论容器化 | 分析Go和Rust做医疗的后端服务
  • Express实现定时任务
  • 飞算科技正在撬动各行业数字化转型的深层变革
  • ch06 部分题目思路
  • OpenCV实现感知哈希(Perceptual Hash)算法的类cv::img_hash::PHash
  • 深入探究编程拷贝
  • 基于Java Spring Boot开发的旅游景区智能管理系统 计算机毕业设计源码32487
  • 4万亿英伟达,凭什么?