流程图
分布式事务 什么是分布式事务分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简单的说,就是一次大的 *** 作由不同的小 *** 作组成,这些小的 *** 作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小 *** 作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
分布式事务的基础 CAPCAP定理,又被叫作布鲁尔定理。对于设计分布式系统来说(不仅仅是分布式事务)的架构师来说,CAP就是你的入门理论。
C (一致性):对某个指定的客户端来说,读 *** 作能返回最新的写 *** 作。对于数据分布在不同节点上的数据上来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
A (可用性):非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。合理的时间指的是请求不能无限被阻塞,应该在合理的时间给出返回。合理的响应指的是系统应该明确返回结果并且结果是正确的,这里的正确指的是比如应该返回50,而不是返回40。
P (分区容错性):当出现网络分区后,系统能够继续工作。打个比方,这里个集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。
是否真的要分布式事务如果只是为了解决几个微服务中事务而过度设计,那有可能只需要将其中的聚合服务整合为一个单机的数据库事务。因为不论任何一种方案都会增加你系统的复杂度,这样的成本实在是太高了,千万不要因为追求某些设计,而引入不必要的成本和复杂度。如果需要分布式事务,目前沉淀下来有以下几种方案
2PC说到2PC就不得不聊数据库分布式事务中的 XA Transactions。 流程示意
在XA协议中分为两阶段:
第一阶段:事务管理器要求每个涉及到事务的数据库预提交(precommit)此 *** 作,并反映是否可以提交.
第二阶段:事务协调器要求每个数据库提交数据,或者回滚数据。
优点: 尽量保证了数据的强一致,实现成本较低,在各大主流数据库都有自己实现,对于MySQL是从5.5开始支持。
缺点:
单点问题:事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,在第二阶段正准备提交的时候事务管理器宕机,资源管理器就会一直阻塞,导致数据库无法使用。
同步阻塞:在准备就绪之后,资源管理器中的资源一直处于阻塞,直到提交完成,释放资源。数据不一致:两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能,比如在第二阶段中,假设协调者发出了事务commit的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了commit *** 作,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。
总的来说,XA协议比较简单,成本较低,但是其单点问题,以及不能支持高并发(由于同步阻塞)依然是其最大的弱点。
TCC关于TCC(Try-/confirm/i-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。 TCC事务机制相比于上面介绍的XA,解决了其几个缺点: 1.解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群。 2.同步阻塞:引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。 3.数据一致性,有了补偿机制之后,由业务活动管理器控制一致性
对于TCC的解释:
Try阶段:尝试执行,完成所有业务检查(一致性),预留必须业务资源(准隔离性)
/confirm/i阶段:确认执行真正执行业务,不作任何业务检查,只使用Try阶段预留的业务资源,/confirm/i *** 作满足幂等性。要求具备幂等设计,/confirm/i失败后需要进行重试。Cancel阶段:取消执行,释放Try阶段预留的业务资源 Cancel *** 作满足幂等性Cancel阶段的异常和/confirm/i阶段异常处理方案基本上一致。流程图
举个简单的例子如果你用100元买了一瓶水, Try阶段:你需要向你的钱包检查是否够100元并锁住这100元,水也是一样的。
如果有一个失败,则进行cancel(释放这100元和这一瓶水),如果cancel失败不论什么失败都进行重试cancel,所以需要保持幂等。
如果都成功,则进行/confirm/i,确认这100元扣,和这一瓶水被卖,如果/confirm/i失败无论什么失败则重试(会依靠活动日志进行重试)
对于TCC来说适合一些:
- 强隔离性,严格一致性要求的活动业务。
- 执行时间较短的业务
MQ事务
在RocketMQ中实现了分布式事务,实际上其实是对本地消息表的一个封装,将本地消息表移动到了MQ内部,下面简单介绍一下MQ事务,流程图
基本流程如下: 第一阶段Prepared消息,会拿到消息的地址。
第二阶段执行本地事务。
第三阶段通过第一阶段拿到的地址去访问消息,并修改状态。消息接受者就能使用这个消息。
如果确认消息失败,在RocketMq Broker中提供了定时扫描没有更新状态的消息,如果有消息没有得到确认,会向消息发送者发送消息,来判断是否提交,在rocketmq中是以listener的形式给发送者,用来处理。
如果消费超时,则需要一直重试,消息接收端需要保证幂等。如果消息消费失败,这个就需要人工进行处理,因为这个概率较低,如果为了这种小概率时间而设计这个复杂的流程反而得不偿失。
---------------------------------------------------------------------------------------------------------------------------------
CAP方式
本期着重CAP模式的解决方案
CAP 是一个EventBus,同时也是一个在微服务或者SOA系统中解决分布式事务问题的一个框架。它有助于创建可扩展,可靠并且易于更改的微服务系统。
目前.netcore下的分布式开源方案为donet.core CAP方法
是基于消息队列,EventBus来实现分布式事务。
应用场景主要有以下两个:
- 分布式事务中的最终一致性(异步确保)的方案
- 具有高可用性的 EventBus
- Demo中流程示意图
Demo中建立了两个数据库
一个为Order,一个为Stock, 两个为不同的数据库,
Cap框架自动生成两个发布与接受信息表
启用webapi,使用postman模拟下订单动作
在提交事务前,发布消息,通知Stock
消费者接收消息,更新数据库,在方法名中代入 [CapSubscribe("")],框架已经为我们做好了,如果失败,则消息队列会重试
订阅后回调:
传入回调:
订阅回调:
发布消息时,可以传入回调主题,在订阅者执行完毕后会回调消息,根据回调消息可以判断订阅者执行成功与否来处理发布者的业务回滚
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)