批量更新主键排序防死锁 标准化规范(错误案例+正确案例+原理复盘)
批量更新主键排序防死锁 标准化规范错误案例正确案例原理复盘一、核心概述数据库批量更新、批量删除场景下90%偶发性死锁、无规律锁超时故障均源于「多线程事务加锁顺序不一致」。该类问题本地单线程测试100%正常仅线上高并发场景触发属于典型的“魔鬼细节隐形故障”。根治核心方案所有批量更新/批量删除执行业务SQL前必须按照数据表主键ID统一升序排序强制全局锁获取顺序一致彻底杜绝循环等待死锁。本规范适用于MySQL InnoDB、达梦DM8所有业务项目统一编码标准。二、故障底层原理深度复盘2.1 锁竞争核心逻辑InnoDB 数据库行锁特性事务执行批量更新时会按照待更新集合的遍历顺序逐条申请排他行锁。成功获取一行锁就执行该行数据修改如果某一行锁获取失败事务会发生阻塞已经获取到的行锁会继续保持持有不会释放。行锁生命周期绑定事务所有行锁统一在事务 commit/rollback 时才释放事务未提交前已持有的行锁会持续阻塞其他并发事务。行锁逐条申请事务结束统一释放中间阻塞已得锁不释放。2.2 死锁产生的必要条件缺一不可多线程并发执行批量更新不同线程的待更新数据列表主键顺序不一致线程互相持有对方需要的行锁形成循环等待2.3 场景模拟真实线上死锁流程假设存在两条数据主键ID140424、ID140425两个业务线程并发批量更新这两条数据线程A加锁顺序140424 → 140425线程B加锁顺序140425 → 140424死锁执行链路线程A 成功锁定 140424等待锁定 140425线程B 成功锁定 140425等待锁定 140424两个线程互相持有对方所需锁资源无限等待数据库死锁检测机制触发强制回滚其中一个事务业务抛出死锁异常死锁### 2.4 场景深度分析场景分析线程A上锁顺序140424 → 140425线程B上锁顺序140425 → 140424这个场景在【应用层for循环逐条执行update】的前提下真的会产生死锁线上非常常见。时序拆解for循环逐条DML不是单条IN线程A事务拿到140424行锁线程B事务拿到140425行锁线程A想去拿140425锁被B持有 → A阻塞等待B释放线程B想去拿140424锁被A持有 → B阻塞等待A释放A等B、B等A形成循环等待InnoDB检测到死锁回滚其中一个事务抛出1213错误。这就是真实线上死锁。⚠️前提必须是循环多次独立update语句每条SQL只更新一行。如果是单条update xxx where id in(140424,140425)不管你in里面id书写顺序怎么写InnoDB会按照聚簇索引从小到大顺序上锁两个线程上锁顺序永远是140424→140425不会死锁。为什么线上这个坑特别多ID集合来源是MQ、前端、RPC返回ID顺序完全随机本地单线程测试不会出现交错时序永远复现不了只有高并发多线程才会出现上面的“交叉拿锁”时序偶发复现条件苛刻属于典型“线上才出、本地好好的”隐形bug。举个极简伪代码就是这个故障的原型//线程A ListLong listA Arrays.asList(140424L,140425L); for(Long id : listA){ updateById(id); //每条都是独立SQL } //线程B ListLong listB Arrays.asList(140425L,140424L); for(Long id : listB){ updateById(id); //每条都是独立SQL }上面代码高并发跑就有概率触发死锁。解决办法循环前把list按主键升序排序。排序后两个线程上锁顺序完全一致就破坏死锁的必要条件。容易混淆的关键点总结执行模式是否会出现截图里的死锁解决手段Java for循环逐条update多条独立SQL✅会线上高频业务层对ID集合主键升序排序单条SQLupdate ... id in(?,?)❌不会内核自动按主键排序上锁业务层排序ID无意义不需要处理补充思考很多网上错误Demo错误拿in()去演示这个死锁场景这就是我们上一篇md博文勘误的那个点。死锁模型本身没问题但是演示工具选错了用in()是复现不出来这个交叉锁必须用循环多条DML。三、错误代码案例线上高频坑核心问题直接使用上游传入的无序List批量更新未做主键排序完全依赖上游数据顺序高并发必触发死锁。/** * 【错误示例】批量更新告警数据高危会产生死锁 * 问题点未排序上游返回的list顺序随机多线程并发锁顺序混乱 */ Transactional(rollbackFor Exception.class) public void batchUpdateAlarm(ListAlarmInfo updateList) { // 直接执行批量更新无任何排序处理 alarmInfoMapper.batchUpdate(updateList); }错误代码风险说明前端、MQ、上游接口返回的数据列表顺序完全随机单线程测试无任何问题无法复现bug线上高并发场景下随机触发死锁、锁超时日志偶发报错极难排查MySQL、达梦数据库均存在该问题无数据库版本豁免四、正确代码案例生产级标准写法核心优化批量操作前强制根据数据表主键ID升序排序统一全局加锁顺序彻底消灭循环等待。/** * 【正确示例】批量更新告警数据防死锁标准写法 * 优化点批量更新前强制主键升序排序 */ Transactional(rollbackFor Exception.class) public void batchUpdateAlarm(ListAlarmInfo updateList) { // 核心必写根据数据库主键ID 升序排序统一全局锁顺序 updateList.sort(Comparator.comparing(AlarmInfo::getId)); // 排序后执行批量更新杜绝死锁 alarmInfoMapper.batchUpdate(updateList); }五、进阶增强版生产终极方案排序去重分批降级适配大数据量、超高并发场景除排序防死锁外规避重复更新、大批量锁堆积、批量全败问题。/** * 【生产终极方案】批量更新 防死锁防重复防锁堆积异常降级 */ Transactional(rollbackFor Exception.class) public void safeBatchUpdateAlarm(ListAlarmInfo updateList) { // 1. 根据主键去重防止同事务重复锁同一行触发约束冲突 ListAlarmInfo distinctList updateList.stream() .collect(Collectors.toMap(AlarmInfo::getId, Function.identity(), (k1, k2) - k1)) .values() .stream() .collect(Collectors.toList()); // 2. 主键升序排序【防死锁核心代码】 distinctList.sort(Comparator.comparing(AlarmInfo::getId)); // 3. 小批量拆分单次50条避免一次性持有大量行锁减少锁超时 ListListAlarmInfo partitionList ListUtils.partition(distinctList, 50); // 4. 分批执行异常降级单条重试避免整批回滚 for (ListAlarmInfo partList : partitionList) { try { alarmInfoMapper.batchUpdate(partList); } catch (DataIntegrityViolationException | LockTimeoutException e) { // 批量冲突降级单条更新保证大部分数据执行成功 log.warn(批量更新锁冲突降级单条执行, e); partList.forEach(info - { try { alarmInfoMapper.updateById(info); } catch (Exception ex) { log.error(单条告警更新失败id:{}, info.getId(), ex); } }); } } }六、关键知识点答疑开发高频疑问6.1 为什么排序就能彻底杜绝死锁所有线程、所有批次统一按照主键从小到大加锁所有人抢锁顺序完全一致只会出现「后线程等待前线程」不会出现双向循环等待从算法层面直接消灭死锁必要条件。6.2 批量新增需要排序吗不需要。批量新增是写入新行、加短暂行锁不存在互相锁对方数据的场景无死锁风险无需排序。6.3 批量删除需要排序吗必须排序。批量删除同样是逐条加行锁锁机制和批量更新完全一致无序删除同样会触发死锁需按主键升序排序。6.4 非主键唯一字段可以排序吗不建议。必须使用物理主键ID排序唯一索引、业务ID无法替代保证锁顺序绝对唯一、稳定。七、强制编码规范纳入代码评审卡点所有batchUpdate / 批量update / 批量delete代码必须存在主键升序排序逻辑无排序一律打回。禁止直接使用上游原始List执行批量DML操作必须经过排序、去重处理。高并发业务批量操作强制使用「排序去重小批量拆分异常降级」终极方案。该规范同时适配 MySQL、达梦DM8全项目统一执行。八、故障总结批量更新死锁不属于数据库bug是典型的编码细节缺失导致的人为故障。问题隐蔽性极强、复现难度极高、线上危害极大仅需一行排序代码即可100%根治是所有后端开发必须掌握的标准化细节规范。九、场景复现更新死锁问题

相关新闻

二叉树_堆的实现

二叉树_堆的实现

1.树树是一种非线性的数据结构,是由m(m>0)个有限节点组成的有层次关系的结合,树的结构中,子树之间是不能有交集的否则就是图,树是递归定义的。常见树的相关术语:⽗结点:若⼀个结点含有⼦结点&#xff0c…

2026/8/18 8:12:28 阅读更多 →
审计专业考研和考证怎么规划

审计专业考研和考证怎么规划

考研和考证,是审计专业学生绕不开的成长主题。很多人在大二大三就开始纠结:应该先全力准备考研,还是趁在校多拿几个证书?其实两者并非对立,如果能结合职业方向做一份清晰的规划,反而能相互借力。这篇文章梳…

2026/8/18 9:08:40 阅读更多 →
TegraRcmGUI 注入 payload 的 5 个关键问题,新手按顺序读完就能上手

TegraRcmGUI 注入 payload 的 5 个关键问题,新手按顺序读完就能上手

TegraRcmGUI 注入 payload 的 5 个关键问题,新手按顺序读完就能上手 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI 第一次进 RCM 的 Switch 是一…

2026/8/17 18:00:10 阅读更多 →

最新新闻

空洞骑士模组管理器 Lumafly 从零上手完整指南:三步告别手动装 Mod 的折腾

空洞骑士模组管理器 Lumafly 从零上手完整指南:三步告别手动装 Mod 的折腾

空洞骑士模组管理器 Lumafly 从零上手完整指南:三步告别手动装 Mod 的折腾 【免费下载链接】Lumafly A cross platform mod manager for Hollow Knight written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/lu/Lumafly 空洞骑士的模组生态有 30…

2026/8/18 10:02:46 阅读更多 →
基于Python婴幼儿个性化辅食推荐系统

基于Python婴幼儿个性化辅食推荐系统

基于Python婴幼儿个性化辅食推荐系统 功能说明 基于 Python Flask SQLite 的 Web 应用,面向家长管理婴幼儿辅食与营养,并提供三类推荐算法(内容推荐、协同过滤、知识推荐)。 1. 用户与婴儿档案 用户注册、登录、退出主面板展示当…

2026/8/18 10:02:46 阅读更多 →
排列组合算法全解析:从公式推导到高效实现与实战应用

排列组合算法全解析:从公式推导到高效实现与实战应用

1. 从“数数”到“算数”:为什么我们需要排列与组合 在编程和算法竞赛里,我们经常遇到一类问题:给你一堆东西,让你数一数有多少种不同的“取法”或“排法”。比如,从5个不同的球里选3个,有多少种选法&#…

2026/8/18 10:02:46 阅读更多 →
DeepSeek 用不起了,切换小米 MiMo 搭建语音交互的实战经验

DeepSeek 用不起了,切换小米 MiMo 搭建语音交互的实战经验

DeepSeek 用不起了,切换小米 MiMo 搭建语音交互的实战经验 DeepSeek 8/17 起要涨价(峰谷价),而小米的 MiMo(mimo-v2.5)刚好出来——一个模型覆盖 ASR TTS Vision 文本,TTS 限时免费&#xff…

2026/8/18 10:02:46 阅读更多 →
7DGroup 开源 dsh-skill-7d-git-commit 插件

7DGroup 开源 dsh-skill-7d-git-commit 插件

文章目录项目信息功能特性项目结构快速开始通过 dsh CLI 安装在 dsh 会话中安装(推荐)构建与测试使用方式提交规范与 GitLab 集成使用集成功能说明背景:为什么要做提交信息校验设计原理:选择 pre-receive 阶段拦截工作原理实践落地…

2026/8/18 10:01:45 阅读更多 →
从零添加你的第一个游戏:Sunshine 应用管理完整指南

从零添加你的第一个游戏:Sunshine 应用管理完整指南

从零添加你的第一个游戏:Sunshine 应用管理完整指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你打开 Sunshine 的 Web 界面,满怀期待地准备串流昨晚刚…

2026/8/18 10:01:45 阅读更多 →

日新闻

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 如果你还停留在"看网课 不停暂停 截图 …

2026/8/18 0:00:57 阅读更多 →
思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 你是不是也经历过这种时刻:设计稿里…

2026/8/18 0:00:58 阅读更多 →
华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, …

2026/8/18 0:00:59 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/18 9:15:35 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/18 9:06:28 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/18 9:04:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/17 18:54:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/17 18:55:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/17 18:55:55 阅读更多 →