SpringBoot + 本地消息表与主库写入不一致:分布式 ID 冲突导致插入失败?雪花算法+唯一索引防重
公司用本地消息表做分布式事务的最终一致性。订单库 INSERT 了订单,消息表 INSERT 了一条"待发送"记录。偶尔消息表 INSERT 失败报唯一键冲突——两个不同的服务实例生成了同样的消息 ID。订单已经入库了,消息没有入库,订单的状态就永远卡在"待发送"。对账的时候才发现有几十笔订单"消息未下发"。 问题出在 ID 生成方式上。他们用的是数据库自增 ID——但在分布式环境下,两个实例各写各的订单库,各自生成了相同的自增 ID(比如都是从 1 开始),然后在消息表里产生了冲突。 今天聊聊怎么用雪花算法生成全局唯一 ID,配合唯一索引做防重,让消息表的 INSERT 不再因为 ID 冲突而失败。 数据库自增 ID 为什么不行 本地消息表的标准做法是: 1. 订单库 INSERT 订单(ID=1001) 2. 消息表 INSERT 消息(msg_id=1001, 关联订单 1001) 3. 定时任务轮询消息表,发送消息 4. 发送成功 → UPDATE 消息状态 = SENT 但如果你有两个服务实例,各自的订单库都有自增 ID=1001。两条订单对应同一个 msg_id=10....