底层没有事务支持时,要自己保证“多步操作要么全做、要么全不做”。常见思路:
- 补偿事务(Saga):把大事务拆成一串本地操作,每步配一个补偿动作;任何一步失败,逆序执行已完成步骤的补偿(下单→扣库存→扣款,失败则退款→回补库存)。语义是最终一致,补偿必须幂等。
- 两阶段提交(2PC):引入协调者,先让所有参与者“准备”(锁定资源、写 undo/redo 日志),全部同意才“提交”。能保证原子性,但协调者单点、同步阻塞、参与者故障时会长时间持锁,需要日志恢复机制。
- 写前日志(WAL)思路:先把意图写入持久日志,再执行;崩溃后按日志回放或回滚——这是数据库自己的做法,可借鉴为应用层的“事务性发件箱”:业务数据与待发消息先同库落表,再由后台中继投递。
- 幂等 + 重试 + 对账:无法回滚就追求可重入,配合定时对账任务发现与修复不一致。
易错点:补偿不是真正的回滚(中间态对外可见,要接受“脏读”窗口);补偿本身也可能失败,必须重试与告警兜底。工程上的第一原则仍是:能放进单个支持事务的存储里,就别自己造分布式事务。