事务是由一组操作构成的可靠的独立的工作单元,事务具备ACID的特性,即原子性、一致性、隔离性和持久性。
大多数情况下,分类是没有意义的一件事。但是分类可以一定程度上,加深理解。
从实现角度来看,Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。
一个JDBC事务不能跨越多个数据库!
容器事务:常见的如Spring事务,主要是J2EE应用服务器提供的,大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。
站在事务管理的角度,可以把Java事务分为本地事务、全局事务、分布式事务。
当事务由资源管理器本地管理时被称作本地事务,如JDBC事务。优点是支持严格的ACID特性,高效可靠,状态可以只在资源管理器中维护,且应用编程模型简单。但不具备分布式事务的处理能力,隔离的最小单位受限于资源管理器,如数据库中的一条记录。
全局事务是指跨越多个独立的组件或服务的事务。全局事务会涉及多个子事务,这些子事务可能分布在不同的计算机或系统上。全局事务的目标是确保多个子事务的一致性,即要么全部执行成功,要么全部回滚。
当事务由全局事务管理器进行全局管理时成为全局事务,事务管理器负责管理全局的事务状态和参与的资源,协同资源的一致提交回滚
全局事务通常由一个协调器来管理,协调器负责协调各个子事务的执行。全局事务具有以下几个阶段:开始(Start)、提交(Commit)和回滚(Rollback)。
全局事务是由资源管理器管理和协调的事务,是一个DTP模型的事务。DTP参考模型指的是X/Open DTP(X/Open Distributed Transaction Processing Reference Model),是X/Open组织定义的一套标准,定义规范和API接口,由各个厂商进行具体的实现。
X/Open DTP定义三个组件(AP,TM,RM)和两个协议(XA、TX):
分布式事务是指多个数据库节点之间的事务,这些节点可以是不同的计算机或系统。分布式事务的目标是确保多个节点之间的数据操作的一致性和原子性。
分布式事务通常有一个全局事务管理器来管理,全局事务管理器负责协调各个节点之间的事务。分布式事务采用两阶段提交(Two-Phase Commit,2PC)和两阶段提交(3PC)协议来确保数据的一致性和原子性。
全局事务和分布式事务都具有处理多个数据操作的一致性和原子性的目标。区别如下:
在传统的RDBMS中,事务具有ACID4个属性:
保证原子性是DBMS的责任:即事务管理器和恢复管理器的责任。遵循ACID原则强调一致性,对成本要求很高,对性能影响很大。
CAP 定理是分布式系统设计中最基础理论。它指出,分布式数据存储不可能同时满足以下三个条件:
CAP 定理表明,在存在网络分区的情况下,一致性和可用性必须二选一。CAP中的一致性与 ACID中一致性截然不同。
CAP的证明:
假设两个节点集{G1, G2}
,由于网络分片导致G1和G2之间所有的通讯都断开。
如果在G1中写,在G2中读刚写的数据, G2中返回的值不可能是刚刚在G1中的写值。
对于分布式数据系统而言,分区容错性是基本要求,否则就不称其为分布式系统。
由于可用性的要求,G2一定要返回这次读请求,因为分区容错性的存在,导致一致性一定是不可满足的。
CAP理论,一个分布式系统不可能同时满足一致性,可用性和分区容错性这三个需求,三个要素中最多只能同时满足两点。
显然,任何横向扩展策略都要依赖于数据分区,软件架构通常必须在一致性与可用性之间做出选择。
BASE,Basically Available、Soft state、Eventually consistent,是对CAP中C和A的延伸。
BASE,基于CAP理论逐步演化而来,核心思想:即便不能达到强一致性(Strong Consistency),但可以根据应用特点采用适当的方式来达到最终一致性的效果。BASE是反ACID的,它完全不同于ACID模型,牺牲强一致性,获得基本可用性和柔性可靠性并要求达到最终一致性。
CAP、BASE理论是NoSQL的理论基础。
即二阶段提交协议(Two Phase Commitment Protocol),2PC通常用来保证数据的强一致性。
XA用于在全局事务中协调多个资源的机制。TM和RM之间采取两阶段提交的方案来解决一致性问题。两节点提交需要一个协调者(TM)来掌控所有参与者(RM)节点的操作结果并且指引这些节点是否需要最终提交。两阶段提交的局限在于协议成本,准备阶段的持久成本,全局事务状态的持久成本,潜在故障点多带来的脆弱性,准备后,提交前的故障引发一系列隔离与恢复难题。
在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败,故而需要协调节点。
2PC中存在两种类型的节点:协调节点(TM)和数据节点(或称协调者与参与者,RM),数据节点可以说是数据在多个节点的备份,协调节点用户协调管理多个数据节点在事务操作中数据的一致性问题。
2PC协议通常分为两个阶段进行,提交请求阶段(Commit Request Phase)或称投票阶段(Voting phase,表决阶段)、与提交阶段(Commit Phase)
第一阶段:
协调者会问所有的参与者结点,是否可以执行提交操作
各个参与者开始事务执行的准备工作:如:为资源上锁,预留资源,写undo/redo log
参与者响应协调者,如果事务的准备工作成功,则回应可以提交,否则回应拒绝提交
第二阶段:
如果所有的参与者都回应可以提交,那么,协调者向所有的参与者发送“正式提交”的命令。参与者完成正式提交,并释放所有资源,然后回应“完成”,协调者收集各结点的“完成”回应后结束这个Global Transaction。
如果有一个参与者回应拒绝提交,那么,协调者向所有的参与者发送“回滚操作”,并释放所有资源,然后回应“回滚完成”,协调者收集各结点的“回滚”回应后,取消这个Global Transaction。
2PC假定节点没有崩溃、任意两个节点的网络都是正常连通的、在写日志的过程中数据不会丢失的前提下。
两阶段提交协议交互构成描述
两阶段提交协议是协调所有分布式原子事务参与者,并决定提交或取消(回滚)的分布式算法。
另一个主要的问题是在TimeOut上,如果第一阶段中,参与者没有收到询问请求,或是参与者的回应没有到达协调者。那么,需要协调者做超时处理,一旦超时,可以当作失败,也可以重试。
如果第二阶段中,正式提交发出后,如果有的参与者没有收到,或是参与者提交/回滚后的确认信息没有返回,一旦参与者的回应超时,要么重试,要么把那个参与者标记为问题结点剔除整个集群,这样可以保证服务结点都是数据一致性的。
第二阶段中,如果参与者收不到协调者的commit/fallback指令,参与者将处于状态未知
阶段,参与者完全不知道要怎么办,比如:如果所有的参与者完成第一阶段的回复后(可能全部yes,可能全部no,可能部分yes部分no),如果协调者在这个时候挂掉。所有的结点完全不知道怎么办(问另的参与者都不行)。为了一致性,要么死等协调者,要么重发第一阶段的yes/no命令。
两段提交最大的问题就是第3项,如果第一阶段完成后,参与者在第二阶没有收到决策,那么数据结点会进入不知所措的状态,这个状态会block住整个事务。也就是说,协调者Coordinator对于事务的完成非常重要,Coordinator的可用性是个关键。
优点:
缺点:
把二段提交的第一阶段拆成两段:询问,然后再锁资源。最后真正提交。
3PC的核心理念是:在询问时并不锁定资源,除非所有人都同意,才开始锁资源。
理论上来说,如果第一阶段所有的结点返回成功,那么有理由相信成功提交的概率很大。这样可以降低参与者Cohorts的状态未知的概率。也就是说,一旦参与者收到PreCommit,意味他知道大家其实都同意修改。
3PC的状态迁移图
注:
缺点:
TCC本质上是一个业务层面上的2PC,要求业务在使用TCC模式时必须实现三个接口Try()
、Confirm()
、Cancel()
。2PC无法解决宕机问题,TCC解决2PC宕机问题的方案:不断重试。
TCC是服务化的二阶段编程模型:
TCC与2PC协议的区别
TCC位于业务服务层而不是资源层,TCC没有单独准备阶段,Try操作兼备资源操作与准备的能力,TCC中Try操作可以灵活的选择业务资源,锁定粒度。TCC的开发成本比2PC高。TCC也属于两阶段操作
一个完整的业务活动由一个主业务服务于若干的从业务服务组成。主业务服务负责发起并完成整个业务活动。从业务服务提供TCC型业务操作。业务活动管理器控制业务活动的一致性,它登记业务活动的操作,并在业务活动提交时确认所有的TCC型操作的Confirm操作,在业务活动取消时调用所有TCC型操作的Cancel操作。
成本:实现TCC操作的成本较高,业务活动结束的时候Confirm和Cancel操作的执行成本。业务活动的日志成本。
使用范围:强隔离性,严格一致性要求的业务活动。适用于执行时间较短的业务,比如处理账户或者收费等等。
特点:不与具体的服务框架耦合,位于业务服务层,而不是资源层,可以灵活的选择业务资源的锁定粒度。TCC里对每个服务资源操作的是本地事务,数据被锁住的时间短,可扩展性好,可以说是为独立部署的SOA服务而设计的。
截止目前,还没有任何一种分布式事务的技术方案,可以满足所有场景的问题。最具代表性的事务模式有四种:AT、TCC、Saga和XA:
AT模式
优势:业务无侵入;轻量,不依赖数据库的高级特性;回滚较少的场景性能高。
劣势:隔离性不高,目前只能支持到接近读已提交(RC,Read Commited)的程度,更高的隔离级别,实现成本将非常高。
TCC模式
优势:适用场景广泛;隔离性和性能都可以做极致优化。
劣势:业务侵入性非常高。
Saga模式
优势:适用于长事务场景。
劣势:有一定业务侵入性;隔离性差。
XA模式
优势:业务无侵入;隔离性好。
劣势:较重的依赖;阻塞协议。
主流的分布式事务解决方案:2PC、3PC、TCC、最大努力消息通知、基于补偿。
服务模式
实际上,TCC的Confirm和Cancel操作可以看做是补偿操作。
柔性事务有两个特性:基本可用和柔性状态。所谓基本可用是指分布式系统出现故障的时候允许损失一部分的可用性。柔性状态是指允许系统存在中间状态,这个中间状态不会影响系统整体的可用性,比如数据库读写分离的主从同步延迟等。柔性事务的一致性指的是最终一致性。
实现:业务处理服务在业务事务提交之前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不是真正的发送。业务处理服务在业务事务提交之后,向实时消息服务确认发送。只有在得到确认发送指令后,实时消息服务才会真正发送。
消息:业务处理服务在业务事务回滚后,向实时消息服务取消发送。消息发送状态确认系统定期找到未确认发送或者回滚发送的消息,向业务处理服务询问消息状态,业务处理服务根据消息ID或者消息内容确认该消息是否有效。被动方的处理结果不会影响主动方的处理结果,被动方的消息处理操作是幂等操作。
成本:可靠的消息系统建设成本,一次消息发送需要两次请求,业务处理服务需要实现消息状态回查接口。
优点:消息数据独立存储,独立伸缩,降低业务系统和消息系统之间的耦合。对最终一致性时间敏感度较高,降低业务被动方的实现成本。兼容所有实现JMS标准的MQ中间件,确保业务数据可靠的前提下,实现业务的最终一致性,理想状态下是准实时的一致性。
实现:业务活动的主动方在完成处理之后向业务活动的被动方发送消息,允许消息丢失。业务活动的被动方根据定时策略,向业务活动的主动方查询,恢复丢失的业务消息。
约束:被动方的处理结果不影响主动方的处理结果。
成本:业务查询与校对系统的建设成本。
使用范围:对业务最终一致性的时间敏感度低。跨企业的业务活动。
特点:业务活动的主动方在完成业务处理之后,向业务活动的被动方发送通知消息。主动方可以设置时间阶梯通知规则,在通知失败后按规则重复通知,知道通知N次后不再通知。主动方提供校对查询接口给被动方按需校对查询,用户恢复丢失的业务消息。
适用范围:银行通知,商户通知。
tcc-transaction
Easytransaction
ByteTCC
dts
能够与Spring事务良好结合
支持Saga/TCC及基于消息的最终一致多种分布式事务解决方案,并易于扩展
具备人工干预的手段