全局事务和共享事务

全局事务和共享事务,是分布式事务的一种中间形式,起到的是承上启下的作用

全局事务

1
2
3
4
5
6
7
8
9
10
回忆

应用场景:单服务多数据源
实现方式:2PC 3PC

弱一致性、最终一致性,解决不了一致性问题

共享事务:通过消息将所有对数据库的改动传送到消息队列服务器,然后通过消息的消费者来统一处理,实现由本地事务保障的持久化操作

问题既然已经出现,又该如何应对。各种解决方案又有什么样的处理方式呢?

全局事务是一种适用于单个服务使用多个数据源场景的事务解决方案。

XA协议

XA协议:定义了全局事务管理器和局部的资源管理器之间的通讯接口。常见的现象有:XADataSource/XAResource

Java对于XA的实现:JTA,定义了事务管理器接口、满足XA规范的资源定义接口。

两段式提交、三段式提交也是基于XA协议的实现

两段式提交
  • 准备阶段:
    由协调者询问,事务的所有参与者是否准备好,如果准备好就回复Prepared,否则回复Non-Prepared
    准备,把所有要提交的操作都写到重做日志记录中。只是不写Commit Record
  • 提交阶段:
    在收到所有参与者回复的Perpared消息后,将本地持久化事务状态改为Commit,然后向所有参与者发送Commit指令,所有参与者立即执行提交操作。
    如果任意一个参与者回复了Non-Prepared消息,或任意一个参与者超时未回复,协调者都会将自己的事务状态持久化为“Abort”之后, 向所有参与者发送Abort指令,参与者立即执行回滚操作
1
2
3
4
5
6
两阶段提交保证成功的前提:
1. 必须假设网络在提交阶段这个短时间内是可靠的,即提交阶段不会丢失消息。
2. 必须假设因为网络分区、机器崩溃或者其他原因而导致失联的节点最终能够恢复,不会永久性地处于失联状态。

出现问题的场景:
当协调者将本地的状态持久为commit后,并提交了本地的事务,这个时候出现的网络中断,再也无法通过网络向参与者发送commit指令,就会导致协调者提交事务,参与者既没法提交也法回滚的情况。从而导致数据不一致。

两段式提交存在的问题

  1. 单点问题:协调者宕机
  2. 性能问题:整个过程要持续到所有参与者中最慢的那个处理完成之后
  3. 一致性风险:当网络稳定性和宕机恢复能力的假设不成立时,会出现严重的一致性问题。
三段式提交

解决两段式提供存在的三个问题中的前两个,也就是单点问题和性能问题,但并没有解决一致性风险。

如何解决的呢

  • 单点问题:
    CanCommit:准备阶段,询问阶段,协调者让每个参与的数据库根据自身状态,评估该事务是否有可能顺利完成。也意味着因某个参与者 提交时发生崩溃而导致全部回滚的风险相对变小了。如果有一个参与者无法完成,这个时候也没有涉及资源被锁住的风险。从这种角度上来看也提升了一些性能。但是也仅仅是在需要回滚的场景中,但是正常提交的情况,性能却多了一个限制 。
    PreCommit:准备阶段,
    DoCommit:提交阶段

共享事务

多个服务共同一个数据源,共享数据库连接,通过数据库中间件的形式,通过消息将所有对数据库的改动传送到消息队列服务器,然后通过消息的消费者来统一处理,实现由本地事务保障的持久化操作