其他分享
首页 > 其他分享> > 分布式事务(三)--XA-2PC-3PC

分布式事务(三)--XA-2PC-3PC

作者:互联网

目录

一、@Transactional存在的问题

1、描述:

Spring的事务只是针对一个数据库是有效的,当同一个事务中包含的操作使用不同的数据库,就无法保证ACID特性,这时候就需要分布式事务了。

后面要学习分布式事务的相关内容,XA规范、2PC、3PC、MySQL对XA分布式事务的支持、Spring多数据库 +
MySQL分布式事务如何实现。

2、最终实现:

把多个数据库的操作,给包裹在一个事务中,如果任何一个操作报错,多个数据库中的操作全部回滚,如果没有报错,那么多个数据库中的操作全部提交。

二、XA规范:

针对上面的问题,X/Open组织定义了分布式事务的模型,有多个角色。

  1. AP:Application,应用程序,就是我们的系统应用。
  2. TM:Transaction Manager,事务管理器,专门用来管理系统夸数据库事务的组件。
  3. RM:Resource Manager,资源管理器,就是数据库MySQL。
  4. CRM:Communication Resource Manager,通信资源管理器,消息中间件,但也可以不用。

TM:根据XA定义的接口规范,跟每个数据库进行通信和交互,通知所有数据库,要么一起提交事务,要么一起回滚。

XA:定义好TM与RM之间的接口规范,就是管理分布式事务的那个组件跟各个数据库之间通信的一个接口。
只是一个规范,具体的实现由数据库产商来提供的,比如说MySQL就会提供XA规范的接口函数和类库实现,等等。

三、2PC--Two-Phase-Commitment-Protocol

X/Open组织定义的一套分布式事务的理论模型,2PC就是基于XA规范的协议,来让分布式事务可以落地,定义了实现分布式事务过程中的细节。
image

1、准备阶段:

TM先发送个prepare消息给各个数据库,让各个库先在本地开个事务,然后执行好SQL,这里各个数据库会准备好随时可以提交或者是回滚,有对应的日志记录的。

然后各个数据库都返回一个响应消息给事务管理器,如果成功了就发送一个成功的消息,如果失败了就发送一个失败的消息。

2、提交阶段:

2.1、第一种情况:

TM收到某个数据库的返回消息SQL执行失败了。或者是TM一直无法收到某个数据库的返回消息确认。

直接判定这个分布式事务失败,然后TM通知所有的数据库,全部回滚,然后各个库都回滚好了以后就通知TM,TM就认为整个分布式事务都回滚了。

2.2、第二种情况:

TM接收到所有的数据库返回的消息都是成功,直接发送个消息通知各个数据库说提交事务,提交好了通知下TM,TM要是发现所有数据库的事务都提交成功了,就认为整个分布式事务成功了。

3、2PC存在的问题

image

3.1、同步阻塞:

执行prepare操作会占用资源,一直到整个分布式事务完成,才会释放资源,这个过程中,如果有其他人要访问这个资源,就会被阻塞住。

3.2、单点故障:

TM是个单点,一旦挂掉就完蛋了。

3.3、事务状态丢失:

即使把TM做成一个双机热备的,一个TM挂了自动选举其他的TM出来,但是如果TM挂掉的同时,接收到commit消息的某个库也挂了。

此时新的TM,压根儿不知道这个分布式事务当前的状态,因为不知道哪个库接收过commit消息,那个接收过commit消息的库也挂了。

3.4、脑裂问题:

如果发生了脑裂问题,那么就会导致某些数据库没有接收到commit消息,那就完蛋了,有些库收到了commit消息,结果有些库没有收到。

四、3PC:针对2PC的优化

1、3pc的流程如下:

1.1、CanCommit阶段:

TM发送CanCommit消息给各个数据库,然后各个库返回个结果。
这时不会执行实际的SQL语句的就是各个库看看自己网络环境是否ready。

1.2、PreCommit阶段:

如果各个库对CanCommit消息返回的都是成功,就进入PreCommit阶段。
TM发送PreCommit消息给各个库,相当于2PC里的阶段一,执行各个SQL语句,只是不提交;
如果有个库对CanCommit消息返回了失败,TM发送abort消息给各个库,结束这个分布式事务。

1.3、DoCommit阶段:

如果各个库对PreCommit阶段都返回了成功,那么发送DoCommit消息给各个库提交事务。
各个库如果都返回提交成功给TM,那么分布式事务成功;
如果有个库对PreCommit返回的是失败,或者超时一直没返回,那么TM认为分布式事务失败。
直接发abort消息给各个库通知回滚,各个库回滚成功之后通知TM,分布式事务回滚成功。

2、相比2PC的改进点:

2.1、引入了CanCommit阶段。

CanCommit阶段证明了每个数据库都是OK的。

2.2、在DoCommit阶段,各个库自己也有超时机制

如果一个库收到了PreCommit还返回成功了。
超时时间到了,还没收到TM发送的DoCommit消息或者是abort消息,直接判定为TM可能出故障了,然后自己就执行DoCommit操作提交事务。

3、3PC的缺陷:

TM在DoCommit阶段发送了abort消息给各个库,结果因为脑裂问题,某个库没接收到abort消息,其他的库提交了事务,还是存在问题。

五、全局事务

针对的是X/Open组织定义了一套分布式事务的模型和规范,DTP(Distributed Transaction Processing
Reference Model),分布式事务处理模型,DTP,TM、RM、AP等等角色的这么一套分布式事务的模型。

全局事务,Global Transaction,是DTP模型中的一个概念。指跨多个数据库的分布式事务。

六、JTA事务

其实是J2EE中的一个概念,Java Transaction API,JTA一套分布式事务的编程API,是按照XA、DTP那套模型和规范来搞的,在J2EE中,单库的事务是通过JDBC事务来支持的。

如果是跨多个库的事务,是通过JTA API来支持的,通过JTA API可以协调和管理横跨多个数据库的分布式事务,一般来说会结合JNDI,J2EE里面很多东西定义的很好,但是在业内使用的时候,最近这些年基本没哪个公司用了。

标签:事务,各个,--,数据库,XA,2PC,TM,分布式
来源: https://www.cnblogs.com/huigelaile/p/15780342.html