真实业务场景死锁案例:电商订单处理

1. 业务场景介绍

场景:电商系统的订单确认流程,需要处理三个核心资源:

  1. 订单锁:防止同一订单被重复处理
  2. 库存锁:防止库存超卖
  3. 支付锁:防止重复支付

2. 死锁发生的真实代码

2.1 订单处理服务

@ServicepublicclassOrderService{@AutowiredprivateRedissonClientredissonClient;@AutowiredprivateInventoryServiceinventoryService;@AutowiredprivatePaymentServicepaymentService;/** * 确认订单(路径1:先锁订单,再锁库存,最后锁支付) */publicvoidconfirmOrder(StringorderId,StringproductId,StringuserId){// 1. 锁定订单RLockorderLock=redissonClient.getLock("order:lock:"+orderId);orderLock.lock();// 线程A持有订单锁try{// 2. 锁定库存RLockinventoryLock=redissonClient.getLock("inventory:lock:"+productId);inventoryLock.lock();// 线程A持有库存锁try{// 3. 锁定支付RLockpaymentLock=redissonClient.getLock("payment:lock:"+userId);paymentLock.lock();// 线程A请求支付锁try{// 业务逻辑:确认订单、扣减库存、创建支付记录doConfirmOrder(orderId,productId,userId);}finally{paymentLock.unlock();}}finally{inventoryLock.unlock();}}finally{orderLock.unlock();}}/** * 快速确认订单(路径2:先锁支付,再锁库存,最后锁订单) */publicvoidquickConfirmOrder(StringorderId,StringproductId,StringuserId){// 1. 锁定支付(与confirmOrder顺序不同)RLockpaymentLock=redissonClient.getLock("payment:lock:"+userId);paymentLock.lock();// 线程B持有支付锁try{// 2. 锁定库存RLockinventoryLock=redissonClient.getLock("inventory:lock:"+productId);inventoryLock.lock();// 线程B持有库存锁try{// 3. 锁定订单(与confirmOrder顺序不同)RLockorderLock=redissonClient.getLock("order:lock:"+orderId);orderLock.lock();// 线程B请求订单锁try{// 业务逻辑:快速确认订单、扣减库存、创建支付记录doQuickConfirmOrder(orderId,productId,userId);}finally{orderLock.unlock();}}finally{inventoryLock.unlock();}}finally{paymentLock.unlock();}}// 其他方法...}

3. 死锁发生的详细流程

3.1 前置条件

  • 线程A:处理用户请求,调用confirmOrder()方法
  • 线程B:处理同一用户的另一个请求,调用quickConfirmOrder()方法
  • 共享资源
    • 订单ID:order_123
    • 商品ID:product_456
    • 用户ID:user_789

3.2 执行时序图

时间点线程A线程B资源状态
T0调用confirmOrder("order_123", "product_456", "user_789")调用quickConfirmOrder("order_123", "product_456", "user_789")所有锁都未被持有
T1获取order:lock:order_123(成功)订单锁被线程A持有
T2获取payment:lock:user_789(成功)订单锁被A持有,支付锁被B持有
T3获取inventory:lock:product_456(成功)订单锁被A持有,支付锁被B持有,库存锁被A持有
T4获取inventory:lock:product_456(等待中…)线程B等待库存锁
T5获取payment:lock:user_789(等待中…)线程A等待支付锁,线程B等待库存锁
T6+无限等待支付锁无限等待库存锁死锁发生!

3.3 死锁的具体表现

现象影响
线程A状态卡在paymentLock.lock()处,无法继续执行
线程B状态卡在inventoryLock.lock()处,无法继续执行
资源状态订单锁、库存锁被A持有;支付锁被B持有
系统表现两个订单请求都无法完成,超时后返回错误
监控表现线程池线程逐渐耗尽,系统响应变慢

4. 死锁的根本原因

4.1 死锁的四个必要条件都满足

条件具体表现
互斥条件每个锁只能被一个线程持有
请求与保持条件线程A持有订单锁和库存锁,同时请求支付锁;线程B持有支付锁,同时请求库存锁
不剥夺条件锁不能被强制剥夺,只能由持有线程主动释放
循环等待条件线程A → 支付锁(被B持有);线程B → 库存锁(被A持有),形成循环等待链

4.2 业务设计缺陷

  1. 锁获取顺序不一致confirmOrder()quickConfirmOrder()两个方法的锁获取顺序不同
  2. 嵌套锁使用不当:同时使用多个嵌套锁,增加了死锁风险
  3. 缺乏超时机制:使用lock()而非tryLock(),导致无限等待
  4. 锁粒度不够细:支付锁按用户ID加锁,可能导致同一用户的所有请求串行化

5. 解决方案:如何避免死锁

5.1 方案1:统一锁获取顺序(推荐)

核心原则所有线程必须按照相同的顺序获取锁

5.1.1 优化后的代码
@ServicepublicclassOrderService{// 定义全局锁顺序:订单锁 → 库存锁 → 支付锁privatestaticfinalList<String>LOCK_ORDER=Arrays.asList("order:lock:","inventory:lock:","payment:lock:");/** * 确认订单(统一锁顺序) */publicvoidconfirmOrder(StringorderId,StringproductId,StringuserId){// 1. 收集所有需要的锁List<String>lockKeys=Arrays.asList("order:lock:"+orderId,"inventory:lock:"+productId,"payment:lock:"+userId);// 2. 按统一顺序排序锁List<String>sortedLockKeys=sortLocks(lockKeys);// 3. 按顺序获取锁List<RLock>acquiredLocks=newArrayList<>();try{for(StringlockKey:sortedLockKeys){RLocklock=redissonClient.getLock(lockKey);lock.lock();acquiredLocks.add(lock);}// 4. 执行业务逻辑doConfirmOrder(orderId,productId,userId);}finally{// 5. 按相反顺序释放锁Collections.reverse(acquiredLocks);for(RLocklock:acquiredLocks){lock.unlock();}}}/** * 快速确认订单(同样的锁顺序) */publicvoidquickConfirmOrder(StringorderId,StringproductId,StringuserId){// 使用完全相同的锁顺序,避免死锁confirmOrder(orderId,productId,userId);}/** * 按预定义顺序排序锁 */privateList<String>sortLocks(List<String>lockKeys){returnlockKeys.stream().sorted(Comparator.comparing(key->{// 根据锁前缀获取排序值for(inti=0;i<LOCK_ORDER.size();i++){if(key.startsWith(LOCK_ORDER.get(i))){returni;}}returnInteger.MAX_VALUE;})).collect(Collectors.toList());}}

5.2 方案2:使用tryLock替代lock

核心原则避免无限等待,设置合理的超时时间

publicvoidconfirmOrder(StringorderId,StringproductId,StringuserId){RLockorderLock=redissonClient.getLock("order:lock:"+orderId);RLockinventoryLock=redissonClient.getLock("inventory:lock:"+productId);RLockpaymentLock=redissonClient.getLock("payment:lock:"+userId);try{// 尝试获取订单锁,最多等待3秒if(!orderLock.tryLock(3,TimeUnit.SECONDS)){thrownewRuntimeException("获取订单锁失败");}try{// 尝试获取库存锁,最多等待3秒if(!inventoryLock.tryLock(3,TimeUnit.SECONDS)){thrownewRuntimeException("获取库存锁失败");}try{// 尝试获取支付锁,最多等待3秒if(!paymentLock.tryLock(3,TimeUnit.SECONDS)){thrownewRuntimeException("获取支付锁失败");}try{doConfirmOrder(orderId,productId,userId);}finally{paymentLock.unlock();}}finally{inventoryLock.unlock();}}finally{orderLock.unlock();}}catch(InterruptedExceptione){Thread.currentThread().interrupt();thrownewRuntimeException("获取锁被中断");}}

5.3 方案3:减少锁的嵌套(推荐)

核心原则最小化锁的使用,避免嵌套锁

@ServicepublicclassOrderService{/** * 优化后:减少锁的嵌套,降低死锁风险 */publicvoidconfirmOrder(StringorderId,StringproductId,StringuserId){// 1. 先检查库存(无锁,快速失败)if(!inventoryService.checkInventory(productId)){thrownewRuntimeException("库存不足");}// 2. 锁定订单(最核心的锁)RLockorderLock=redissonClient.getLock("order:lock:"+orderId);try{if(!orderLock.tryLock(5,30,TimeUnit.SECONDS)){thrownewRuntimeException("获取订单锁失败");}// 3. 再次检查库存(双重检查,防止并发更新)if(!inventoryService.checkInventory(productId)){thrownewRuntimeException("库存不足");}// 4. 扣减库存(原子操作,数据库乐观锁)inventoryService.deductInventory(productId);// 5. 创建支付记录(幂等设计,无需锁)paymentService.createPaymentRecord(orderId,userId);// 6. 确认订单doConfirmOrder(orderId,productId,userId);}catch(InterruptedExceptione){Thread.currentThread().interrupt();thrownewRuntimeException("获取锁被中断");}finally{orderLock.unlock();}}}

6. 死锁监控与排查工具

6.1 生产环境监控

工具用途关键指标
JMX监控JVM线程状态线程数量、阻塞线程数、死锁检测
SkyWalking分布式链路追踪慢调用、超时调用、异常调用
Prometheus + Grafana系统监控线程池使用率、响应时间、错误率
Redisson监控分布式锁监控锁获取次数、锁等待时间、锁持有时间

6.2 死锁排查命令

# 1. 查看JVM线程状态,检测死锁jstack-l<PID>|grep-A20"Found one Java-level deadlock"# 2. 查看线程详情jstack<PID>>jstack.txt# 分析jstack.txt文件,寻找BLOCKED状态的线程# 3. 使用VisualVM图形化工具jvisualvm# 启动VisualVM,连接到JVM进程,查看线程状态

7. 总结

7.1 死锁的本质

死锁的本质是资源的无序竞争+无限等待

7.2 真实业务场景的死锁预防

最佳实践效果
统一锁获取顺序打破循环等待条件
使用tryLock替代lock避免无限等待
最小化锁持有时间减少死锁发生概率
减少锁的嵌套降低死锁复杂度
实现幂等设计减少对锁的依赖
定期检测死锁及时发现和处理死锁

7.3 最终建议

库存扣减等核心业务场景中:

  1. 优先使用数据库乐观锁,减少对分布式锁的依赖
  2. 使用细粒度锁,按商品ID/订单ID加锁
  3. 设置合理的tryLock参数,避免无限等待
  4. 统一锁获取顺序,避免循环等待
  5. 实现幂等性,确保重复执行不会产生副作用

通过以上措施,可以有效避免真实业务场景中的死锁问题,确保系统的高可用性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1119210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习毕设项目推荐-人工智能基于python深度学习的餐桌美食识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

2026年评价高的广州专利翻译,广州俄语翻译,广州法律翻译公司口碑推荐清单 - 品牌鉴赏师

引言在2026年,翻译服务行业在全球化的浪潮下愈发重要,尤其是在广州这样的国际化大都市,专利翻译、俄语翻译、法律翻译等专业领域的需求不断增长。为了给广大客户提供一份客观、公正、权威的广州翻译公司推荐清单,我…

【计算机毕业设计案例】基于python机器学习识别水果的成熟度

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

2026最新PLC控制柜企业top5推荐榜!优质生产厂家及服务商解析/选择指南 - 全局中转站

引言 随着工业4.0战略深入推进,工业自动化控制系统作为智能制造的核心枢纽,其稳定性与可靠性直接决定生产效率与工程安全。当前市场中,PLC控制柜产品同质化严重,设计不规范、工艺粗糙、售后响应滞后等问题频发,据…

2026年口碑好的IGBT散热器,CPU散热器,高密度散热器厂家选型参考手册 - 品牌鉴赏师

引言在当今科技飞速发展的时代,散热设备在各个领域的地位愈发关键,无论是通信行业的服务器芯片,还是新能源汽车的动力电池,都需要高效的散热解决方案以确保其稳定运行。为了给广大企业和消费者提供权威、可靠的散热…

学长亲荐!专科生必看TOP8AI论文写作软件测评

学长亲荐&#xff01;专科生必看TOP8AI论文写作软件测评 2026年专科生AI论文写作工具测评&#xff1a;为何值得一看&#xff1f; 随着人工智能技术的不断发展&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上琳琅满目的AI写作软件&a…

吐血推荐专科生10款AI论文写作软件测评

吐血推荐专科生10款AI论文写作软件测评 2026年专科生必备的AI论文写作工具测评 在当前学术环境日益严格的背景下&#xff0c;专科生在撰写论文时面临诸多挑战&#xff0c;如选题困难、文献检索繁琐、格式规范不熟悉等。为帮助学生更高效地完成论文写作&#xff0c;笔者基于2026…

2026年热门的抛光粉,抛光粉汽车玻璃,不锈钢抛光粉厂家优质排行 - 品牌鉴赏师

引言在 2026 年的工业市场中,抛光粉作为一种关键的工业耗材,在汽车玻璃、不锈钢等多个领域发挥着至关重要的作用。为了给广大需求者提供一份客观、公正、真实的优质抛光粉厂家排行,我们联合国内相关行业协会,依据行…

LabVIEW 2025 安装图解:从下载到激活 一步到位

LabVIEW 2025 是 NI 推出的图形化编程工具,不用写代码,拖图标、连连线就能做测试测量、数据采集、工业控制类项目,适合工程师、科研人员和学生。 核心新亮点 1、调试更省心:断点、探针整合到一个窗口,数值直接显示…

2026年评价高的激光器水冷板,真空钎焊水冷板,搅拌摩擦焊水冷板厂家行业精选名录 - 品牌鉴赏师

引言在2026年的工业发展进程中,激光器水冷板、真空钎焊水冷板以及搅拌摩擦焊水冷板在众多领域发挥着至关重要的作用,其性能的优劣直接影响到相关设备的运行效率与稳定性。为了帮助广大用户在市场上众多的水冷板厂家中…

全域质量管理:数字化时代,如何让质量贯穿每一个环节?

在制造业竞争日益激烈的今天,质量已成为企业生存与发展的生命线。然而,传统的质量管理模式往往局限于“事后检验”,难以从根本上预防问题、提升品质。 随着数字化浪潮的推进,覆盖企业全流程、全角色、全数据的 “全…

当了3年产品经理,我终于把后端甩开了:一个 AIGC 应用的诞生当了3年产品经理,我终于把后端甩开了:一个 AIGC 应用的诞生

“这个需求很简单,怎么要排期一周?” 作为一名产品经理,这句话我不知在心里默念了多少遍。我每天都在创造、设计,但每一个想法从文档到现实,都隔着一道名为“研发资源”的墙。 我曾以为这是无法逾越的规则,直到我…

【计算机毕业设计案例】基于卷神经网络python深度学习的餐桌美食识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

计算机深度学习毕设实战-机器学习基于python卷积神经网络训练形状识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

2026年1月安徽推进式搅拌机,脱硫搅拌机,搅拌机厂家权威推荐,搅拌效率与市场口碑解析 - 品牌鉴赏师

引言在当今工业生产领域,搅拌机作为关键设备,广泛应用于化工、食品、制药、新能源等众多行业。其性能的优劣直接影响到生产效率、产品质量以及企业的经济效益。因此,如何选择一家优质可靠的搅拌机厂家成为了众多企业…

深度学习毕设项目:基于python人工智能训练形状识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

动点问题中的定值与最值(2024年安徽省芜湖一中自主招生第17题)

动点问题中的定值问题与最值问题,含隐圆模型。专题:几何综合 \(\qquad \qquad \qquad \qquad\) 题型:动点问题中的定值与最值 \(\qquad \qquad \qquad \qquad\) 难度系数:★★★★【题目】 (20…

2026tpep防腐钢管源头厂家+外pe内环氧粉末防腐钢管厂 - 栗子测评

2026tpep防腐钢管源头厂家+外pe内环氧粉末防腐钢管厂家推荐!TPEP防腐钢管作为外PE内环氧粉末防腐钢管的主流类型,凭借双层防腐的卓越性能、灵活的施工特性及长久的使用寿命,成为水利、石油天然气、市政建设等领域长距…

使用Docker部署postgresql - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2026年优秀的数据中心液冷管,半导体设备液冷管,充电桩液冷管厂家行业头部榜单 - 品牌鉴赏师

引言在当今科技飞速发展的时代,数据中心、半导体设备以及充电桩等领域对液冷技术的需求日益增长,液冷管作为液冷系统的关键组件,其质量和性能直接影响着整个系统的运行效率和稳定性。为了给行业内的企业和用户提供一…