知其然,知其所以然
分布式事务 2026-10-17

事务消息:半消息与回查

用真实的 RocketMQ 5.5.1 和 MySQL 实测事务消息:半消息在本地事务提交前对消费者不可见(1643 ms),回滚则丢弃;返回 UNKNOW 时 broker 回查并按订单是否存在 COMMIT;生产者 kill -9 后,没声明 topic 的新生产者收不到回查,3 次后半消息被丢弃,声明了 topic 的新生产者 2997 ms 收到回查并 COMMIT;回查一直 UNKNOW 到上限也会丢弃。

分布式事务 事务消息 半消息 回查 RocketMQ MySQL 真实验证 动画演示
分布式事务 2026-10-17

幂等键:去重表的设计

实测幂等键的去重表设计:200 个 key 各 8 个并发重复请求,先查后插让业务执行了 1590 次,先插唯一键正好 200 次;去重记录与业务不在同一个事务里,1000 个 key 里丢 201 个或重复 210 个,同一个事务 0;状态型幂等键与租约;去重表 30 万 key 13.5 MiB;保留期短于重试窗口会再执行一次。

分布式事务 幂等 幂等键 去重表 MySQL 唯一索引 真实验证 动画演示
分布式事务 2026-10-17

消息重复与乱序:消费端怎么处理

实测消费端怎么处理重复和乱序:RabbitMQ 先处理再 ack 重复 1 条、先 ack 再处理丢 1 条、auto-ack 丢 199 条;两个消费者快慢不同乱序 12 条;Kafka 按实体做 key 实体内 0 条乱序、不设 key 1322 条;版本号解决乱序(status 错 58 到 0)、去重解决重复(counter 错 92 到 0),合用才全对。

分布式事务 消息重复 消息乱序 RabbitMQ Kafka 版本号 去重 MySQL 真实验证 动画演示
分布式事务 2026-10-17

最终一致:对账与修复

实测最终一致的对账与修复:10 万订单全量对账 0.36 s 发现全部 2068 个分歧(丢失、重复、金额不一致、孤儿)、0 误报;只比最近 1 小时只能发现 5%,支付库时钟慢 5 分钟会出 311 个误报;宽限期 1 秒消除途中订单的误报;幂等修复后重新对账 0 分歧,再修复 0 动作。

分布式事务 最终一致 对账 修复 MySQL 真实验证 动画演示
分布式事务 2026-10-17

分布式锁与事务的关系

实测分布式锁与事务的关系:Redis 锁能把 800 次读改写从丢 699 次变成 0 丢失,但比原子 UPDATE 慢 10 倍;持有者被 SIGSTOP 冻住 1 秒、锁过期后 A 醒来照样写,计数器 2 变 1(写前检查也没用);fencing token 让旧持有者的写入被存储端拒绝;持锁者 kill -9 后转账少了 100,锁不是事务。

分布式事务 分布式锁 Redis fencing token MySQL 真实验证 动画演示
分布式事务 2026-10-17

乐观锁:版本号与 CAS

实测乐观锁:不保护的读改写 800 次丢 697 次;version CAS 丢 0 次,但同一行 8 线程每次成功平均试 7.02 次、32 线程 27.57 次,吞吐从 4573 降到 417 成功/秒;无冲突时一次成功;按状态值 CAS 有 208 / 300 次被 ABA 欺骗,version CAS 0 次;随机指数退避把 409 提高到 3332 成功/秒。

分布式事务 乐观锁 CAS version ABA MySQL 真实验证 动画演示
分布式事务 2026-10-17

库存扣减:超卖的几种防止方式

实测六种库存扣减方式抢 1000 件:先读后写 3000 个都成功超卖 2000;FOR UPDATE、条件 UPDATE、乐观锁、分片、Redis Lua 都是 0 超卖;乐观锁因争用只有 1121 请求/秒、库存充足时成功数也只有 2323 到 2349(应为 3000);Redis 没持久化被 kill -9 后按 MySQL 重建,超卖 526 件。

分布式事务 库存扣减 超卖 Redis MySQL 乐观锁 真实验证 动画演示
分布式事务 2026-10-17

订单状态机:状态流转与并发更新

实测订单状态机:朴素 UPDATE 接受 30 条流转(25 条非法),带源状态条件只接受 5 条合法的;并发的支付与取消 1000 单读后写全部矛盾,条件 UPDATE 0 个;重复回调 1500 次只触发 500 次副作用;随机 2 万次尝试日志重放全部一致;触发器拦住绕过应用的非法 UPDATE。

分布式事务 订单状态机 并发更新 幂等 MySQL 触发器 真实验证 动画演示
分布式事务 2026-10-17

全局锁与回滚日志:AT 模式的原理(自己实现一个最小版本)

手写一个最小的 AT 模式并实测:分支本地提交时写前后镜像到 undo_log 并申请全局锁;全局回滚按前镜像恢复;全局锁让 T2 等 825 ms,没有全局锁 T1 回滚会因脏写失败;普通写入绕过全局锁同样造成脏写;读到被回滚的 900 占 98%;一次分支更新 357 µs 变成 1991 µs。

分布式事务 AT 模式 undo_log 全局锁 Seata MySQL 真实验证 动画演示
分布式事务 2026-10-17

事务协调者、管理者与资源管理者:角色分工(手写原型)

手写 TM / RM / TC 三个独立进程的最小原型并实测:一次全局事务 12 次 HTTP 调用;TM 崩溃后 TC 超时(1.5 s)扫描器回滚;TC 在二阶段被 kill -9,重启后从 tc_db 恢复继续;RM 暂时失败 TC 退避重试,一直失败则全局锁一直被占、别的事务等 1034 ms 失败。

分布式事务 TM RM TC 事务协调者 超时回滚 崩溃恢复 二阶段重试 MySQL 真实验证 动画演示
分布式事务 2026-10-17

Percolator 风格的事务:主锁与次锁

手写最小的 Percolator 风格事务并实测:原子性押在主锁那一次提交上;预写后 kill -9,读到的人等 1486 ms(TTL 1500 ms)后回滚;主锁提交后 kill -9,读到的人 0.7 ms 前滚;压力下会处理锁的快照读 215 次检查总额 0 次错,不管锁的读 3339 次错 11 次。

分布式事务 Percolator 主锁 次锁 快照隔离 MySQL 真实验证 动画演示
分布式事务 2026-10-17

Raft 日志复制:提交条件

用真实的 3 节点 etcd 实测 Raft 的提交条件:多数(2/3)落盘才提交;杀 1 个 follower 写入延迟不变(7.74 → 7.83 ms)、重启后 164 ms 追上;只剩 1 个节点时写入超时,多数恢复后那次超时的写入反而被提交;手写模拟论文图 8:数副本数提交旧任期条目会被覆盖;延迟只取决于最快的多数(31.0 vs 31.5 ms)。

分布式事务 Raft 日志复制 提交条件 etcd 线性一致 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号