分布式事务

2018-09-07  本文已影响0人  萌妈码码

终于看到一篇总结得很不错的关于微服务架构中分布式事务的处理方案,很喜欢。转来供以后参考。Enjoy~~ All of them are brilliant ideas!!

概念澄清

柔性事务 vs. 刚性事务

刚性事务是指严格遵循ACID原则的事务, 例如单机环境下的数据库事务.

柔性事务是指遵循BASE理论的事务, 通常用在分布式环境中, 常见的实现方式有: 两阶段提交(2PC), TCC补偿型提交, 基于消息的异步确保型, 最大努力通知型.

通常对本地事务采用刚性事务, 分布式事务使用柔性事务.

最佳实践

先上结论, 再分别介绍分布式事务的各种实现方式.

  • 如果业务场景需要强一致性, 那么尽量避免将它们放在不同服务中, 也就是尽量使用本地事务, 避免使用强一致性的分布式事务.
  • 如果业务场景能够接受最终一致性, 那么最好是使用基于消息的最终一致性的方案(异步确保型)来解决.
  • 如果业务场景需要强一致性, 并且只能够进行分布式服务部署, 那么最好是使用TCC方案而不是2PC方案来解决.

注意: 以下每种方案都有不同的适用场合, 需要根据实际业务场景来选择.

两阶段提交(2PC)

两阶段提交(Two Phase Commit, 2PC), 具有强一致性, 是CP系统的一种典型实现.

两阶段提交, 常见的标准是XA, JTA等. 例如Oracle的数据库支持XA.

下图是两阶段提交的示意图:

2pc

图的上半是两阶段提交成功的演示, 下半是两阶段提交失败的演示. 关于两阶段提交网上有很多经典的讲解, 这里就不细说了, 可以参考前面的链接.

缺点

TCC (Try-Confirm-Cancle)

TCC, 是基于补偿型事务的AP系统的一种实现, 具有最终一致性.

TCC流程

下面以客户购买商品时的付款操作为例进行讲解:

优点

对比与前面提到的两阶段提交法, 有两大优势:

注意事项

适用场景

举例: 红包, 收付款业务.

异步确保型

通过将一系列同步的事务操作变为基于消息执行的异步操作, 避免了分布式事务中的同步阻塞操作的影响.

这个方案真正实现了两个服务的解耦, 解耦的关键就是异步消息和补偿性事务.

这里以一个例子作为讲解:

异步确保型

执行步骤如下:

  1. MQ发送方发送远程事务消息到MQ Server;
  2. MQ Server给予响应, 表明事务消息已成功到达MQ Server.
  3. MQ发送方Commit本地事务.
  4. 若本地事务Commit成功, 则通知MQ Server允许对应事务消息被消费; 若本地事务失败, 则通知MQ Server对应事务消息应被丢弃.
  5. 若MQ发送方超时未对MQ Server作出本地事务执行状态的反馈, 那么需要MQ Servfer向MQ发送方主动回查事务状态, 以决定事务消息是否能被消费.
  6. 当得知本地事务执行成功时, MQ Server允许MQ订阅方消费本条事务消息.

需要额外说明的一点, 就是事务消息投递到MQ订阅方后, 并不一定能够成功执行. 需要MQ订阅方主动给予消费反馈(ack)

注意事项

适用场景

例如:

最大努力通知型

这是分布式事务中要求最低的一种, 也可以通过消息中间件实现, 与前面异步确保型操作不同的一点是, 在消息由MQ Server投递到消费者之后, 允许在达到最大重试次数之后正常结束事务.

适用场景

交易结果消息的通知等.

小结

不管是同步事务中的事务管理器(协调者), 还是异步事务中使用的消息中间件,若要达到一致性保证,都需要使用带有同步复制语义的 HAC 提供的高可用和高可靠特性,这些都是以性能为代价的,无疑成为了SOA 架构中的典型性能瓶颈之一.


本文链接: http://blog.csdn.net/congyihao/article/details/70195154

上一篇下一篇

猜你喜欢

热点阅读