两阶段提交(XA)

XA 规范主要定义了全局事务管理器(TM)和局部资源管理器(RM)之间的接口。本地的数据库如 mysql 在 XA 中扮演的是 RM 角色。

XA一共分为两阶段:

  • 第一阶段(prepare):即所有的参与者RM准备执行事务并锁住需要的资源。参与者ready时,向TM报告已准备就绪。对于数据库来说,准备阶段指在重做日志(redo log)中记录所有操作的内容(与真正提交的区别在于没有最后一句 commit)。
  • 第二阶段 (commit/rollback):当事务管理者(TM)确认所有参与者(RM)都 ready 后,向所有参与者发送 commit 命令。 数据库只在第二阶段执行 commit 命令,通常能快速完成。
  • 如果有任何一个参与者 prepare 失败,那么TM会通知所有完成 prepare 的参与者进行回滚。

目前主流的数据库基本都支持XA事务,包括 mysql、oracle、sqlserver、postgre,数据库的 TM 与 RM 通常都是由数据库自己扮演,TM 一般来说是在 RM 中选举产生。

特点:

  • 简单易理解,开发较容易
  • 对资源进行了长时间的锁定,并发度低
  • 如果 TM 宕机,所有节点都受影响

SAGA

SAGA 的核心思想是将长事务拆分为多个本地短事务,由Saga事务协调器协调。如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作。

Saga 一旦到了 Cancel 阶段,那么 Cancel 在业务逻辑上是不允许失败了。如果因为网络或者其他临时故障,导致没有返回成功,那么 TM 会不断重试,直到 Cancel 返回成功。

特点:

  • 并发度高,不用像 XA 事务那样长期锁定资源
  • 需要定义正常操作以及补偿操作,开发量比 XA 大
  • 一致性较弱,对于转账,可能发生A用户已扣款,最后转账又失败的情况

TCC(Try-Confirm-Cancel)

TCC 分为3个阶段:

  • Try 阶段:尝试执行,完成所有业务检查(一致性),预留必须业务资源(准隔离性)
  • Confirm 阶段:确认执行,真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 操作要求具备幂等设计,Confirm 失败后需要进行重试。
  • Cancel 阶段:取消执行,释放 Try 阶段预留的业务资源。Cancel 阶段的异常和 Confirm 阶段异常处理方案基本上一致,要求满足幂等设计。

上面的转账作为例子,通常会在Try里面冻结金额,但不扣款,Confirm里面扣款,Cancel里面解冻金额。

TCC 的 Confirm/Cancel 阶段在业务逻辑上是不允许返回失败的,如果因为网络或者其他临时故障,导致不能返回成功,TM会不断的重试,直到Confirm/Cancel返回成功。

特点:

  • 并发度较高,无长期资源锁定。
  • 开发量较大,需要提供Try/Confirm/Cancel接口。
  • 一致性较好,不会发生SAGA已扣款最后又转账失败的情况
  • TCC适用于订单类业务,对中间状态有约束的业务

本地消息表

写本地消息和业务操作放在一个事务里,保证了业务和发消息的原子性,要么他们全都成功,要么全都失败。

容错机制:

  • 扣减余额事务失败时,事务直接回滚,无后续步骤
  • 轮序生产消息失败, 增加余额事务失败都会进行重试

本地消息表的特点:

  • 不支持回滚
  • 轮询生产消息难实现,如果定时轮询会延长事务总时长,如果订阅binlog则开发维护困难

适用于可异步执行的业务,且后续操作无需回滚的业务

https://segmentfault.com/a/1190000040321750