在单机情况下,实现事务十分简单,但是如果是分布式系统,核心操作分布在不同的机器上,比如订单-支付-库存,这个流程必须要使用事务控制,但其是分布式的,这种情况单机事务无法满足,于是就有了分布式事务

1,XA 协议

XA 协议都是数据库底层支持的,例如 Oracle,Mysql 都支持二阶段提交

1,2PC 二阶段提交

二阶段提交有两个重要的角色:

  • 事务协调者,掌控着整个事务的走向
  • 事务参与者,参与部分事务的操作

    1,整体流程

    image.pngimage.png
    第一阶段
  1. 协调者会给每个参与者发送 Prepare 请求
  2. 参与者接收到 Prepare 请求后,各自执行本地事务,但是不提交,之后给协调者发送 Done 完成消息
  3. 协调者接收到所有的参与者的 Done 完成消息后,确认都完成了,此时分布式事务进入第二阶段
  4. 如果有参与者 Prepare 执行失败,那么所有的参与者必须回滚事务,协调者将会给参与者发送 Abort 请求

image.pngimage.png
第二阶段

  1. 在确认所有参与者都执行完成后,向所有参与者发送 Commit 提交请求
  2. 参与者接收到 Commit 请求后,进行本地事务提交,并向协调者发送 Done 完成消息
  3. 协调者接收到所有参与者的 Done 完成消息,整个分布式事务流程结束

    2,二阶段提交的不足

  • 性能问题,XA 协议遵循强一致性,即所有参与者都要一致,只有所有参与者都成功,协调者才会允许成功
  • 协调者单点故障问题,整个流程中,协调者十分重要,协调者一旦挂掉,整个事务将卡住无法进行下去
  • 丢失消息导致数据不一致,因为整个流程依赖网络,难免会发生有节点失去连接问题,无法提交或回滚事务

    2,3PC 三阶段提交

    三阶段提交相比二阶段提交,引入了 CanCommit 阶段和 超时机制

  • CanCommit,在收到所有参与者 Prepare 阶段的 Done 完成结果时,不直接发送 Commit 请求,而是发送 Cancommit 询问参与者是否都可以提交,满足后再发送 Commit 请求

  • 超时机制,即当参与者迟迟接收不到协调者的 Commit 请求时,将会自动进行本地 Commit,这样就解决了协调者单点故障问题,但是性能问题数据不一致没有得到解决.

    2,MQ 事务

    利用消息中间件来让参与者去提交或者回滚事务,协调者不必等待所有参与者的应答,这样满足了高性能,但是数据强一致性没有得到满足,只满足了最终一致性

    3,TCC 事务

    TCC 事务分为三个指令:

  • Try

  • Commit
  • Cancel

相比于 XA协议的 2PC,TCC 是在业务代码层面控制的,它要求每个业务操作都需要提交 Try,Commit,Cancel 三个操作,对应用的侵入比较大,且实现难度大,但是性能高,可以自定义数据库操作的粒度,降低锁冲突