我们知道ACID(原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)定义了单个数据库操作的事务性,这样我们就能放心的使用数据库,而不用担心数据的一致性,操作的原子性等等。由于数据库同时可以并发的给多个应用、多个会话线程使用,这样就涉及到了锁,隔离级别和数据可见性等一系列工作,好在关系数据库都已经帮我们解决了这些问题。
但是在SOA、分布式服务化和微服务架构的大背景下,数据拆分到多个不同的库已经是常态,这种改造或者设计中,同一个业务处理涉及到的关联数据生命周期可能要贯穿到多个不同的数据库,如果没有事务保证,那么数据的一致性或者正确性就会收到破坏,账就可能会错乱了,平台或者客户就会产生损失了。如何保证数据的事务性,则是一个非常有意思的话题。传统的数据库和消息系统一般都是支持XA分布式事务,通过一个TM事务管理器协调各个RM资管管理器,每个RM管理自己的本地事务,通过两阶段提交2PC来保障一致。
由于CAP的不可能三角约束下,我们大部分时候选择了从ACID到BASE(Basically Available基本可用, Soft-state柔性状态, Eventually consistent最终一致),这样分布式事务我们一般也从XA变成了TCC(Try-Commit-Cancel),把分布式事务的控制权从底层资源层(比如数据库)挪到了业务实现层,从而通过释放数据库层的锁,来提升性能和灵活性。具体情况可以参阅下面的各个参考文档。
1、TXC模式,使用MVCC快照模式 blog.csdn.net/m0_38110132…
一、原理介绍: TXC模式命名来源于淘宝,实现原理是在执行SQL之前,先查询SQL的影响数据,然后保存执行的SQL快走信息和创建锁。当需要回滚的时候就采用这些记录数据回滚数据库,目前锁实现依赖redis分布式锁控制。
二、模式特点:
2、TCC事务模式
一、原理介绍: TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务、 Confirm:确认执行业务、 Cancel: 取消执行业务。
二、模式特点: 该模式对代码的嵌入性高,要求每个业务需要写三种步骤的操作。
该模式对有无本地事务控制都可以支持使用面广。
数据一致性控制几乎完全由开发者控制,对业务开发难度要求高。
发现一个好玩的,有人实现了一个可以给dubbp和spring cloud提供XA分布式事务的开源框架。
LCN distributed transaction framework, compatible with dubbo, spring cloud and Motan framework, supports various relational databases。
地址:
在单一数据节点中,事务仅限于对单一数据库资源的访问控制,称之为本地事务。几乎所有的成熟的关系型数据库都提供了对本地事务的原生支持。
但是在基于微服务的分布式应用环境下,越来越多的应用场景要求对多个服务的访问及其相对应的多个数据库资源能纳入到同一个事务当中,分布式事务应运而生。
关系型数据库虽然对本地事务提供了完美的ACID原生支持。
但在分布式的场景下,它却成为系统性能的桎梏。如何让数据库在分布式场景下满足ACID的特性或找寻相应的替代方案,是分布式事务的重点工作。
在不开启任何分布式事务管理器的前提下,让每个数据节点各自管理自己的事务。
它们之间没有协调以及通信的能力,也并不互相知晓其他数据节点事务的成功与否。
本地事务在性能方面无任何损耗,但在强一致性以及最终一致性方面则力不从心。
XA协议最早的分布式事务模型是由X/Open国际联盟提出的X/Open Distributed Transaction Processing(DTP)模型,简称XA协议。
基于XA协议实现的分布式事务对业务侵入很小。
它最大的优势就是对使用方透明,用户可以像使用本地事务一样使用基于XA协议的分布式事务。 XA协议能够严格保障事务ACID特性。
严格保障事务ACID特性是一把双刃剑。
事务执行在过程中需要将所需资源全部锁定,它更加适用于执行时间确定的短事务。
对于长事务来说,整个事务进行期间对数据的独占,将导致对热点数据依赖的业务系统并发性能衰退明显。 因此,在高并发的性能至上场景中,基于XA协议的分布式事务并不是最佳选择。
如果将实现了ACID的事务要素的事务称为刚性事务的话,那么基于BASE事务要素的事务则称为柔性事务。 BASE是基本可用、柔性状态和最终一致性这三个要素的缩写。
在ACID事务中对隔离性的要求很高,在事务执行过程中,必须将所有的资源锁定。
柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面上移至业务层面。通过放宽对强一致性要求,来换取系统吞吐量的提升。
基于ACID的强一致性事务和基于BASE的最终一致性事务都不是银弹,只有在最适合的场景中才能发挥它们的最大长处。 可通过下表详细对比它们之间的区别,以帮助开发者进行技术选型。
本地事务 | 两(三)阶段事务 | 柔性事务 | |
---|---|---|---|
业务改造 | 无 | 无 | 实现相关接口 |
一致性 | 不支持 | 支持 | 最终一致 |
隔离性 | 不支持 | 支持 | 业务方保证 |
并发性能 | 无影响 | 严重衰退 | 略微衰退 |
适合场景 | 业务方处理不一致 | 短事务 & 低并发 | 长事务 & 高并发 |
由于应用的场景不同,需要开发者能够合理的在性能与功能之间权衡各种分布式事务。
强一致的事务与柔性事务的API和功能并不完全相同,在它们之间并不能做到自由的透明切换。在开发决策阶段,就不得不在强一致的事务和柔性事务之间抉择,使得设计和开发成本被大幅增加。
基于XA的强一致事务使用相对简单,但是无法很好的应对互联网的高并发或复杂系统的长事务场景;柔性事务则需要开发者对应用进行改造,接入成本非常高,并且需要开发者自行实现资源锁定和反向补偿。
整合现有的成熟事务方案,为本地事务、两阶段事务和柔性事务提供统一的分布式事务接口,并弥补当前方案的不足,提供一站式的分布式事务解决方案是ShardingSphere分布式事务模块的主要设计目标。