十年架构师经验总结:分布式事务解决方案

求职攻略 阅读(1794)
博狗bodog88在线

a79a5fb9-2cc2-48f2-8279-7046f785c9f5

分布式事务的实现主要有以下五个选项:

XA方案TCC方案本地消息表可靠消息最终一致性方案尽力通知方案

两阶段提交计划/XA计划

所谓的XA解决方案,即:两阶段提交,具有事务管理器的概念,它负责协调多个数据库(资源管理器)的事务。事务管理器首先询问每个数据库您准备好了吗?如果每个数据库都回复正常,则正式提交事务并对每个数据库执行操作;如果任何数据库没有回答ok,则回滚事务。

这种分布式事务方案更适合单个应用程序中跨多个库的分布式事务,并且因为它在很大程度上依赖于数据库级别来处理复杂事务,所以效率非常低,并且它绝对不适用于高并发场景。如果你想玩,那么你可以基于Spring + JTA来做,你可以自己找一个演示,你就会知道。

这种方案很少使用。一般来说,如果系统内的多个库之间存在此类操作,则不符合要求。我可以告诉你一些情况。现在微服务,一个大系统分为几十甚至几百个服务。通常,我们的规则和规范要求每个服务只能运行自己的一个数据库。

如果你想操作对应其他服务的库,你就不允许直接连接到其他服务的库,违反了微服务架构的规范,你会随便跨越随机访问,数百种服务,全是凌乱,这样的服务不是如果法律得到管理而无法管理,可能会出现其他人更正数据的情况,并且图书馆会被其他人编写和挂起。

66307553-b9bb-41c4-91ec-5b1c251f5563

如果要运行其他人服务的库,则必须通过调用其他服务的接口来实现它。绝对不允许交叉访问其他人的数据库。

33c18fa36901495a95dc63a5725ae7d3

TCC计划

TCC的全名是:尝试,确认,取消。

尝试阶段:此阶段是指检测每个服务的资源以及锁定或保留资源。确认阶段:此阶段是关于在每个服务中执行实际操作。取消阶段:如果任何服务的业务方法执行不正确,则需要补偿,即执行已成功执行的业务逻辑的回滚操作。 (成功执行这些执行)

据说这种程序很少有人使用,我们使用的程序较少,但也有一些情况。因为这个事务回滚实际上很大程度上依赖于你自己的代码来回滚和补偿,所以它会导致巨大的补偿代码,非常恶心。

例如,我们一般涉及金钱,处理货币,支付,交易相关的情景,我们将使用TCC,严格保证分布式交易全部成功,或全部自动回滚,严格保证资金的正确性确保资金没有问题。

并且最好花更少的时间在您的业务上。

但说实话,一般尽量不要这样做,手写回滚逻辑或补偿逻辑,这太恶心了,业务代码很难维护。

ad0ad055c86c4ad99af2dd11af5e21a1

本地消息表

本地消息列表实际上是来自外国ebay的一组想法。

这可能意味着这样的事情:

消息表中的数据;然后系统将此消息发送给MQ; B数据在执行其他业务操作时,如果消息已被处理,则事务将被回滚,因此它将不会重复处理消息;系统成功执行后,更新本地消息表的状态和A系统消息表的状态;如果B系统无法处理,则不更新消息表状态,则系统A将计时。扫描您自己的消息表。如果有未处理的消息,它将再次发送给MQ,让B再次处理;即使B事务失败,此方案也保证了最终的一致性,但A将重新发送消息,直到B在那里成功。

此解决方案的最大问题是它严重依赖数据库的消息表来管理事务。如果它是一个高并发场景怎么办?咋扩张怎么样?所以它很少使用。

05234c6d20c340eaabe5060e4f4ec236

可靠的消息最终一致性方案

这意味着根本不使用本地消息表,而是直接基于MQ实现事务。例如,Ali的RocketMQ支持消息事务。

93f1ef67-e8d4-435a-9032-8fd069fbae84

可能意味着:

系统首先将准备好的消息发送给mq。如果准备好的消息未能发送,则取消操作。如果消息成功发送,则执行本地事务。如果成功,则发送mq以发送确认消息。如果失败,只需告诉mq回滚消息;如果发送确认消息,则B系统将接收确认消息,然后执行本地事务; mq会自动轮询所有准备好的消息来回调你的界面,并问你,这条消息是不是本地事务失败,所有没有发送确认的消息,继续重试还是回滚?一般来说,您可以检查数据库以查看之前是否执行了本地事务。如果它被回滚,那么它将在这里回滚。这是为了避免可能的本地事务执行成功,但确认消息无法发送。在这种情况下,如果系统B的事务失败怎么办?重试,自动重试直到成功,如果不成功,或者为了重要的资本业务回滚,例如B系统本地回滚,找到通知系统A的方法也回滚;或通过手动回滚和手动补偿发送警报。这非常合适。目前,国内互联网公司大多都在玩这个游戏。您想使用RocketMQ支持,还是依赖ActiveMQ? RabbitMQ的?我将一组类似的逻辑封装出来,一般的想法是这样的。

355770f1d66949f6b0a1a25b065ae182

尽力而为通知计划

该计划的一般含义是:

系统执行本地事务后,向MQ发送消息;将消耗MQ的最大努力通知服务。此服务将使用MQ,然后将其写入数据库进行记录,或将其放入内存队列。然后调用系统B的接口;如果系统B成功执行,则可以;如果系统B无法执行,那么尽力通知服务将尝试定期召回系统B,重复N次,最后放弃。

所需的Java架构师的信息后面可以跟私信,回复“数据”以接收免费的架构视频资料,记得要点赞!