UPSERT并发竞争下的「幽灵ID」脏数据
前言线上遇到一类隐蔽生产故障程序运行无报错、事务正常提交却源源不断产生僵尸脏数据。当两个事务并发对同一业务单号执行UPSERT时其中一个事务会被唯一索引排他记录锁阻塞被阻塞的事务唤醒后因唯一键冲突降级执行UPDATE不会新增主表数据。依托MyBatis-Plus雪花ID策略实体提前在内存生成主键若下游直接使用这个ID创建子记录就会出现子表有数据、主表无匹配记录的「幽灵ID」脏数据。环境说明MySQL InnoDBRC、RR隔离级别均会复现业务单号建立唯一索引并发事务均使用UPSERT写入主键策略使用 IdType.ASSIGN_ID 雪花算法。完整并发执行时序1. 事务A、事务B同时处理同一业务单号 a 执行UPSERT2. MP在SQL执行前分别为两个实体在内存预生成独立雪花ID3. 事务A率先抢占唯一索引排他记录锁执行SQL事务尚未提交4. 事务B检测到锁冲突进入阻塞等待。备注RC、RR隔离级别下事务B均无法读取事务A未提交的数据因此预先查询判断业务单号 a 是否存在无法规避该并发问题5. 事务A执行commit数据成功写入数据库6. 事务B被MySQL唤醒再次校验唯一索引发现单号 a 已存在7. 事务B进入UPDATE分支仅更新已有记录不会新增主表行。幽灵ID产生核心原理雪花ID由应用内存提前生成和数据库执行结果无关。即便UPSERT最终走入更新分支没有插入新数据实体对象依旧保留预先生成的雪花ID。业务代码直接读取实体ID用于新增明细、流水等子记录。结果事务B携带的雪花ID仅存在于JVM内存数据库不存在该主键也就是幽灵ID最终滋生大量悬浮子表脏数据。补充IdType.AUTO 自增主键在UPSERT下的表现自增主键行为和雪花ID有明显区别1. 常规写法新建实体 idnull 。UPSERT进入UPDATE分支时无法回调主键实体ID维持null。只要代码增加ID非空判断就能规避脏数据2. 危险写法代码手动提前 setId() 设置占位ID。更新分支不会覆盖实体属性占位ID保留同样会生成幽灵ID。整体来看自增主键默认场景风险更低但并非绝对安全。生产级解决方案1. UPSERT执行完成后禁止直接使用实体内的主键。必须根据唯一键业务单号重新查询数据库拿到真实持久化主键2. 校验UPSERT执行影响行数int affectRows mapper.upsert(entity); // 返回1新增成功返回2冲突更新禁止使用当前实体主键关联子数据3. 针对业务唯一单号增加分布式锁保证同一单号串行执行从源头消除并发争抢4. 核心主数据业务不要无脑滥用UPSERT可拆分新增、更新逻辑。总结同一唯一键并发UPSERT时被锁阻塞的事务最终降级执行更新、不会新增主表记录。雪花算法 IdType.ASSIGN_ID 预先在内存生成主键极易诞生幽灵ID是高频风险点自增主键 IdType.AUTO 仅在手动赋值实体ID的特殊场景下会踩坑。

相关新闻

使用KeyStore Explorer生成带SAN的HTTPS证书并在SpringBoot中集成

使用KeyStore Explorer生成带SAN的HTTPS证书并在SpringBoot中集成

1. 项目概述:为什么我们需要自己动手生成带SAN的HTTPS证书?在SpringBoot项目里启用HTTPS,很多人的第一反应是去申请一个免费的Let‘s Encrypt证书,或者干脆花钱买一个。这当然没问题,但对于开发、测试、内网部署或者需…

2026/8/2 3:15:51阅读更多 →
技术管理者实践指南:从自动化到智能化的四化演进路径

技术管理者实践指南:从自动化到智能化的四化演进路径

1. 从“四化”的迷思到实践地图:一个技术管理者的深度拆解每次听到“自动化、信息化、数字化、智能化”这“四化”被并列讨论,尤其是在各种战略报告和厂商方案里,我总有种复杂的感受。一方面,这确实是技术演进和业务融合的一条清晰…

2026/8/2 3:15:51阅读更多 →
C# TCP/IP通信实战:从Socket基础到async/await异步编程

C# TCP/IP通信实战:从Socket基础到async/await异步编程

1. 项目概述:从零构建一个C# TCP/IP通信骨架在软件开发的网络通信领域,TCP/IP协议栈是基石,而Socket则是程序员与这个基石交互最直接的“手柄”。无论你是想开发一个即时通讯软件的后台服务,为工业上位机搭建一个可靠的数据采集通…

2026/8/2 3:13:51阅读更多 →
IDEA运行Java程序全解析:从环境配置到调试优化实战指南

IDEA运行Java程序全解析:从环境配置到调试优化实战指南

1. 项目概述:从“能跑”到“跑得好”的跨越每次看到有新手朋友在群里问“我的Java代码在IDEA里怎么运行不了”,或者截图一个红彤彤的报错不知所措时,我都会想起自己刚入门那会儿。那时觉得,在IDE里点一下绿色三角箭头就能运行程序…

2026/8/2 4:34:25阅读更多 →
Cocos Creator 3.4.2环境搭建全攻略:从Node.js到VS Code的避坑指南

Cocos Creator 3.4.2环境搭建全攻略:从Node.js到VS Code的避坑指南

1. 项目概述:为什么需要一份详尽的Cocos Creator环境搭建指南?如果你正准备踏入Cocos Creator游戏开发的大门,或者刚从2.x版本升级到3.x,那么“环境搭建”这个看似简单的第一步,很可能就是你遇到的第一个“拦路虎”。我…

2026/8/2 4:34:25阅读更多 →
超图神经网络MHGNN:从高阶关系建模到药物发现的实战解析

超图神经网络MHGNN:从高阶关系建模到药物发现的实战解析

1. 从“方剂配伍”到“超图建模”:一个药物发现新范式的诞生在传统中医药与现代计算科学的交叉点上,有一个问题困扰了研究者们很久:如何系统性地、可解释地预测一味草药能缓解哪些症状?这听起来像是一个经典的“药物-靶点”预测问…

2026/8/2 4:34:25阅读更多 →
Unity协程WaitForSeconds深度解析:五大陷阱与性能优化实践

Unity协程WaitForSeconds深度解析:五大陷阱与性能优化实践

1. 项目概述:为什么WaitForSeconds值得深究?在Unity开发中,协程(Coroutine)几乎是每个开发者都会接触到的核心异步编程工具。而WaitForSeconds,作为协程里最常用的“等待”指令,其使用频率之高&…

2026/8/2 4:34:25阅读更多 →
3D动画反派情感塑造:从木棍权杖到催泪核心的技术解析

3D动画反派情感塑造:从木棍权杖到催泪核心的技术解析

《小马宝莉最催泪反派:那根权杖,只是一根木棍。》这个标题看似是动画剧情分析,但结合技术博客的定位,我们可以从动画制作技术、角色建模、情感计算、3D渲染等角度切入,探讨如何通过技术手段实现催泪效果。本文将重点分…

2026/8/2 4:34:25阅读更多 →
B2118 验证子串

B2118 验证子串

题目描述输入两个字符串,验证其中一个串是否为另一个串的子串。输入格式两行,每行一个字符串。输出格式若第一个串 s1​ 是第二个串 s2​ 的子串,则输出(s1) is substring of (s2);否则,若第二个串 s2​ 是第一个串 s1…

2026/8/2 4:32:25阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 在数字媒体创作领域,视频编辑处理的质量损…

2026/8/2 1:29:34阅读更多 →
AI辅助本科论文写作:8大工具评测与高效使用指南

AI辅助本科论文写作:8大工具评测与高效使用指南

1. 本科生论文写作的AI辅助现状本科毕业论文是每个大学生必须跨越的一道坎。记得我当年写论文时,光是文献检索就花了整整两周时间,打印的参考文献堆满了半个书桌。如今AI技术的发展为学术写作带来了革命性变化,合理使用这些工具可以节省80%以…

2026/8/2 2:32:55阅读更多 →
如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为抢不到热门演唱会门票…

2026/8/2 2:09:20阅读更多 →