分布式事务综述 😄
基础理论:CAP、BASE
分布式事务算法、思想
2PC(强一致性)
有数据阻塞、不一致的情况
3PC(强一致性)
有数据阻塞、不一致的情况
TCC(最终一致)
TCC分布式事务模型相对于XA协议,其特征在于它不依赖资源管理器对分布式事务的支持,而是通过对业务逻辑的分解来实现分布式事务。对于一个具体的业务服务,其需要业务系统提供三段业务逻辑:
- 1.Try:完成所有业务检查,预留必须的业务资源;
- 2.Confirm:用于提交,真正执行业务逻辑,不做任何业务检查且只使用try阶段预留的业务资源。因此只要try操作成功,confirm也能成功;此外confirm还需要满足幂等性,保证分布式事务有且只有一次成功;
- 3.Cancel:用于回滚,释放Try阶段预留的业务资源,同样也需要满足幂等性。
举例子来说,拿10元买一瓶水这一操作,Try阶段,查询钱包中是否有10元并锁住这10元,查询是否有水并锁住这一瓶水;如果try阶段失败则执行cancel,
释放10元和这一瓶水,保证幂等性;如果都成功则进行confirm,确认扣除10元和一瓶水,confirm失败会重试需要保证幂等性;
TCC实现的二阶段提交是在业务层面而不是在资源层面,有效避免了XA二阶段提交占用资源锁过长导致的性能低下问题。但是TCC模型对业务代码有很大的入侵,业务改造成本高。
最大努力通知方式(最终一致)
BEN(Best Effort Notification),它是一种不保证强一致性的方法,通过异步通知(常见的是消息中间件实现)来达到事务的一致性,
即尽力保证事务成功,但不能完全保证,主要应用在金融交易场景中。
具体来说,分布式事务最大努力通知通常用于以下场景:
- 1、异步通知:当某个服务需要通知其他服务或组件进行后续操作时,可以采用异步通知的方式,发出通知后即可继续自身的操作,而不需要等待被通知的服务的响应。
- 2、最终一致性:在分布式系统中,因为网络延迟、故障等原因,无法保证所有相关的服务或组件都能够及时收到通知。因此,采用最大努力通知的方式来处理事务,可以更好地适应分布式系统的不确定性,最终保证系统达到一致的状态。
在实际应用中,分布式事务最大努力通知可能会导致以下情况:
- 通知失败:由于网络故障、接收方服务不可用等原因,通知可能会失败。
- 重复通知:为了确保通知的可靠性,可能需要定时重试通知操作,这可能导致接收方收到重复的通知。
为了应对这些情况,通常需要在接收方设计幂等性的接收机制,以确保即使接收到重复的通知,也不会对系统状态产生额外影响。
总的来说,分布式事务最大努力通知是一种在分布式系统中处理事务的方法,它通过异步、灵活的通知机制来适应分布式系统的复杂性,但同时也需要考虑通知可能失败和重复通知等情况。
对于时间不敏感的业务,短信、邮件通知等。尽最大努力进行推送消息保证事务数据的最终一致性。
分布式事务解决方案
XA协议
全称eXtended Architecture,它是一个分布式事务协议,通过二阶段提交来保证强一致性。XA协议通常实现在数据库资源层,直接作用于资源管理器,且大部分数据库支持XA协议。
- 优点:
由于其作用于资源管理器上,所以基于XA协议实现的分布式产品对业务几乎没有入侵; - 缺点:
资源被锁定时间长,性能低,不适用高并发场景;
本地消息表
本地消息表是将分布式事务分解成多个本地事务,通过本地消息表跟消息中间件连接起来最终实现分布式事务。再该模型中分为事务主动方和事务被动方,事务主动方需要建立并维护本地消息表,该消息表记录事务进行的状态。
事务流程如下:
- 1.事务主动方首先进行自己的业务处理并将后续处理写入消息表,这两步在同一个本地事务中保持一致性;
- 2.事务主动方轮询消息表,向消息中间件发送消息;
- 3.消息被动房消费消息,处理本地事务并将结果写会消息中间件;
- 4.事务主动方监听消息中间件更新本地消息表;
- 5.各个步骤可能会出现异常,可以会导致消息重复等问题,所以要保证幂等性。
缺点:
- 1.写本地消息表和业务处理耦合在一起,难以做成通用性;
- 2.本地消息表是通过写在数据库中进行实现,需要做额外的磁盘的IO操作,不适用高并发;
RocketMQ消息事务
RocketMQ中采用的消息事务。RocketMQ消息事务需要在发送消息时进行两段提交,保证发送消息和本地事务的原子性;此外RocketMQ本身提供存储功能,相当于是对本地消息表的一个内部封装,对事务消息提供持久化支持。
消息事务流程如下:
-
- 实现发送消息的二阶段提交,首先消息生产者预发送消息(half message),若收到成功回复则执行本地事务;若失败则直接取消后续操作;
-
- 若消息生产者本地事务处理成功则向服务端(MQ broker)发送commit请求,此时消息便在broker中生效,消费者可进行消费;若消息失败则回滚;此外,因为网络原因或其他情况broker一直未收到commit或者rollback请求则会主动问询事务状态,并根据问询结果进行commit或者rollback;
-
- 事务被动方消费消息,进行本地事务;若事务被动方本地事务失败则会不断重试,达到一定次数后触发报警由人工介入处理。若事务成功则整个分布式事务处理完成。
事务消息不仅适用于上游事务对下游事务无依赖的场景,还可以与一些传统分布式事务架构相结合,而 MQ 的服务端作为天生的具有高可用能力的协调者,使得我们未来可以基于MQ提供一站式轻量级分布式事务解决方案,用以满足各种场景下的分布式事务需求。
不采用的原因:需要强依赖中间件的能力,耦合较深,不易迁移,性能较差
Ali的TXC中间件
TXC(Taobao Transaction Constructor)是一款高性能、高可靠、接入简单的分布式事务中间件,用于解决分布式环境下的事务一致性问题。2014年的
TXC特点:
- 最终一致性(牺牲部分一致性和隔离性,可通过配置更改性能与隔离性之间的平衡点)
- 代码入侵少(不需要程序员改造业务逻辑,通过注解形式便可实现,开发便捷)
- 跨多应用事务(与HSF结合)
三种模式:
- 标准模式(AT模式)
- 自定义模式(MT模式)
- 重试模式(RT模式)
开源版TXC:Seata
官网链接:
https://seata.apache.org/zh-cn/docs/overview/what-is-seata/
事务模式
提供了四种事物模式: AT、TCC、SAGA 和 XA
-
AT
-
TCC
-
Sega
Saga 模式是分布式事务中长事务的一种解决方案,Seata 中 Saga 模式的理论基础是 Hector & Kenneth 在 1987 年发表的论文 Sagas。下图(来自官网)是 Seata 中 Saga 模型:
在 Saga 模式中,如果一部分分支事务已经提交成功,当其中一个分支事务提交失败,状态机就会触发所有提交成功的分支事务进行回滚。
分支事务中提交和回滚的逻辑需要由业务代码来实现。
-
XA
历史
参考:
1、【最大努力通知-实现分布式事务】
https://blog.csdn.net/Fireworkit/article/details/135174577