REQUIRES_NEW 双倍连接数这个账很实在,我顺着补两处。
业务表幂等做在 uk_order_no 我完全赞成,但 catch 之后不能无脑 return success。 直接返回只在「第一次已完整跑完」时对;如果第一次崩在插业务表和发通知之间,第二次撞唯一键直接返回,通知就永远丢了。所以撞键后要查出来看业务状态机——status 已终态就跳过,中间态就补做后续步骤。消息表插入失败当投递失败重试,这个思路同理,重试得让消费端能识别「这单处理到哪一步了」。
逐条 UPDATE 我也站你这边,但可以再省一层。 不用 CAS 抢占,直接按 id 取模分片(实例 i 只扫 id % n == i),天然并行无争抢,代价是实例数变化时要停一轮扫描。中小规模比 CAS 简单,也就省掉了 status=3 那套状态机。真到单表日增百万再上 IN 批量+反查,你说的时钟同步坑确实在,反查判错就是重复投。
undo_log 同库同数据源这句是 AT 的命门,多数据源场景下它由 DataSourceProxy 管理,每个被代理的数据源各建一张,别只给主库建,代理漏配一个库回滚时就直接镜像拿不到。
最后 HikariCP maxPoolSize 双倍估的时候,记得和 MySQL max_connections 一起算,N 实例 × 双倍很容易打爆,这个比连接池本身更常出问题。
共用表 + topic 前缀我认同,uk_biz(biz_id, topic) 本来就带了 topic,中小项目够用,等真到拆库再说。