================================================================
防止脑裂分布式事务框架 —— 三个 node 服务器进程级模拟
================================================================

[启动] 拉起 txn / user / shop 三个 node 服务器进程 ...
        user -> http://127.0.0.1:6001   shop -> http://127.0.0.1:6002   txn -> http://127.0.0.1:6003

[种子] 用户 u1=100 / u2=500 / u_low=10；商家 m1{s1:10,s2:5} / m2{s1:3}

事务状态机流转规则：
  INIT         -> FROZEN, MANUAL_REVIEW, ROLLBACK
  FROZEN       -> MANUAL_REVIEW, ROLLBACK, SUCCESS
  ROLLBACK     -> MANUAL_REVIEW, ROLLED_BACK
  任意非终态    -> MANUAL_REVIEW（重试耗尽，人工复核）


================================================================
案例1 正常下单：用户扣余额 + 商家扣库存，对外表现为原子事务
================================================================
  初始：用户 u1 余额=100，商家 m1/s1 库存=10
  状态流转：
    INIT           创建事务 a466d2aa
    INIT           -> FROZEN         a466d2aa
    FROZEN         -> SUCCESS        a466d2aa
  结果：余额=70（应 70），库存=9（应 9）
  幂等验证通过：同一幂等号重放直接返回既有结果，无重复扣减。
  [PASS] case1_normal

================================================================
案例2 冻结失败：用户余额不足，冻结中途失败 -> ROLLBACK -> ROLLED_BACK
================================================================
  初始：用户 u_low 余额=10，商家 m1/s1 库存=9
  状态流转：
    INIT           创建事务 98fea3f9
    INIT           -> ROLLBACK       98fea3f9
    ROLLBACK       -> ROLLED_BACK    98fea3f9
  结果：余额=10，库存=9（商家冻结已被解冻，库存不变）
  [PASS] case2_freeze_fail

================================================================
案例3 提交中失败：用户已扣真实余额，商家 COMMIT 被下游拒绝 -> 返还余额 + 解冻库存
================================================================
  状态流转：
    INIT           创建事务 8fcb4f19
    INIT           -> FROZEN         8fcb4f19
    FROZEN         -> ROLLBACK       8fcb4f19
    ROLLBACK       -> ROLLED_BACK    8fcb4f19
  结果：余额=500（应返还回 500），库存=9（应不变 9）
  [PASS] case3_commit_fail_refund

================================================================
案例4 网络恢复：店家分片隔离 -> 滞留 INIT -> 恢复后由轮询器/死信重连续做
================================================================
  下单提交：店家不可达，事务滞留 INIT（第1次尝试），下次重试=1792511456.74
  店家分片恢复，轮询器开始扫描非终态事务...
  状态流转：
    INIT           创建事务 353835d0
    INIT           -> FROZEN         353835d0
    FROZEN         -> SUCCESS        353835d0
  终态：SUCCESS（attempts=1）
  结果：余额=470（应 470），库存=8（应 8）
  [PASS] case4_network_recover

================================================================
案例5 节点自治回滚：店家宕机期间无法下发回滚，重启后节点自检自行补偿
================================================================
  1) 冻结双方成功 -> FROZEN；店家 COMMIT 瞬时故障，事务滞留 FROZEN（attempts=1）
  2) 店家进程已宕机；强制回滚：用户已扣余额已返还，店家解冻补偿因节点不可达而挂起，事务滞留 ROLLBACK（attempts=2）
  3) 重启店家节点，启动自检插件查询未完成事务并核对本地冻结...
  状态流转：
    INIT           创建事务 4a8b618b
    INIT           -> FROZEN         4a8b618b
    FROZEN         -> ROLLBACK       4a8b618b
  终态：ROLLED_BACK
  结果：余额=470（应返还回 470），库存=8（应不变 8）
  [PASS] case5_node_selfcheck

================================================================
案例6 离线对账：孤儿冻结自动解冻 + 全局状态库丢失可备份恢复
================================================================
  注入孤儿冻结：user/u1 存在冻结标记 orphan_txn_0001，但全局无此事务单据
  已做全局事务状态库快照备份：C:\Users\User\Desktop\防止脑裂构想和模拟\防止脑裂事务框架\data\txn\backup\snapshot_1792511461479.json
  对账检出孤儿冻结 -> 自动解冻 + 告警。
    告警: 对账：解冻孤儿冻结 user/orphan_txn_0001
  孤儿冻结已清理，u1 余额不变（=70）。
  全局事务状态库主数据被清空（模拟彻底损毁）-> 对账提示可用备份恢复。
  从快照恢复：C:\Users\User\Desktop\防止脑裂构想和模拟\防止脑裂事务框架\data\txn\backup\snapshot_1792511461479.json，恢复事务单据 5 条
  [PASS] case6_reconcile_orphan

================================================================
案例7 重试耗尽：店家持续不可达，指数退避达到上限 -> MANUAL_REVIEW 触发告警
================================================================
  下单提交：店家 m2 持续不可达，事务滞留 INIT，指数退避重试...
  终态：MANUAL_REVIEW（attempts=3，最大=3）
  告警: [13c534bcdb564faf] 重试耗尽(3)，进入人工复核: shop_db[shard_1.json] 节点不可达/隔离
  已停止无限重试，转入 MANUAL_REVIEW，等待人工复核。
  [PASS] case7_retry_exhaust

================================================================
运行结果汇总
================================================================
  [PASS] 案例1 正常下单  -  INIT->FROZEN->SUCCESS，幂等重放通过
  [PASS] 案例2 冻结失败回滚  -  商家已冻结->解冻，库存不变
  [PASS] 案例3 提交中失败退款  -  已扣余额返还，库存不变
  [PASS] 案例4 网络恢复续做  -  轮询器+死信重连后 SUCCESS
  [PASS] 案例5 节点自治回滚  -  店家重启后自检补偿，事务 ROLLED_BACK
  [PASS] 案例6 离线对账  -  孤儿冻结自动解冻+告警，全局库可备份恢复
  [PASS] 案例7 重试耗尽人工复核  -  退避达上限 -> MANUAL_REVIEW + 告警

本次产生的告警：
  [orphan_unfreeze] 对账：解冻孤儿冻结 user/orphan_txn_0001
  [manual_review] [13c534bcdb564faf] 重试耗尽(3)，进入人工复核: shop_db[shard_1.json] 节点不可达/隔离

三个 node 进程已关闭。
总体结果: 全部通过
