zoukankan      html  css  js  c++  java
  • 分布式事务(三)XA、2PC、3PC Diamond

    一、@Transactional存在的问题

    1、描述:

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

    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认为整个分布式事务都回滚了。

    2.2、第二种情况:

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

    3、2PC存在的问题

    image

    3.1、同步阻塞:

    执行prepare操作会占用公共资源,因为第一阶段不会提交本地事务,直到整个分布式事务完成,才会释放资源。

    3.2、单点故障:

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

    3.3、事务状态丢失:

    当前participant的状态只有自己和coordinator知道。

    即使把TM做成一个双机热备,一个TM挂了自动选举其他的TM,唯一一个接收到commit消息的数据库也挂了。

    新的TM根本不知道这个分布式事务当前的状态,哪个数据库接收到commit,哪个没接收到。

    在新的TM启动之前,其他participant就会进入不能rollback和commit的阻塞状态。

    3.4、脑裂问题:

    如果发生了脑裂问题,就会导致某些数据库没有接收到commit消息,有些库没有收到,就会出现不一致的问题。

    四、3PC:

    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里面很多东西定义的很好,但是在业内使用的时候,最近这些年基本没哪个公司用了。

  • 相关阅读:
    H5C3综合案例
    CSS3 3D转换
    CSS3 动画
    CSS3 2D转换
    html+css入门基础案例之页面设计
    0tcpdump使用与ping
    redis计划(yet)
    为什么hashmap以2的倍数作为桶的长度,同时以2作为扩容倍数
    maven SNAPSHOT
    maven dependengcy:tree 查看maven依赖树(母项目指定pluginManagement)
  • 原文地址:https://www.cnblogs.com/huigelaile/p/15780342.html
Copyright © 2011-2022 走看看