分布式事务GTS学习记录

   我们常用的事务是数据库事务,在单机单应用单数据库场景下才适用的,随着分布式系统越来越普及,数据的一致性问题如何解决,业界目前主要有3种解决方案:

    一、两阶段提交。

      第一阶段,所有事务参与者将执行结果的成功与否反馈给事务协调者,但是不提交。

      第二阶段,事务协调者根据返回的结果,决定是全部提交,还是全部不提交。

      该方案可以保证事务的4个特性ACID。

          A原子性,一个事务内的操作要么全部成功,要么全部失败。

          C一致性,事务提交后,数据必须满足完整性约束。

          I隔离性,事务间的操作是独立的,互不影响。

          D持久性,事务提交后,数据永久生效。

      该方案不足之处,可能子事务B在执行时,要访问还未提交事务的子事务A锁定的资源,导致锁等待,吞吐量会遇到瓶颈,导致性能不高。


   二、TCC

         TCC是两阶段提交的一个变种,在事务的ACID和性能间找到一个平衡点,部分牺牲一致性和隔离性,保证事务最终的一致性。

        T,也就是Try,它会执行完所有的操作,并提交(准确说是临时提交),不会导致锁等待。

        C,也就是Confirm,如果Try操作全部成功,则所有操作Commit。

        C,也就是Cancel,如果Try操作没有全部成功,则所有操作Rollback。

     分布式事务GTS学习记录_第1张图片

     该方案总体来看,满足业务需求的前提下,还保证了性能,在业界用的比较多。


   三、基于消息的最终一致性方案

         分布式事务GTS学习记录_第2张图片

   将本地A操作和远程B操作的消息作为一个事物,一起提交,要么都成功,要么都失败,缺点是,对业务代码的侵入性太大,实现起来复杂。


   下面介绍下分布式事务GTS(Global Transaction Service),是阿里旗下的一个中间件产品,它支持的事务操作包括Sql操作,RPC服务,消息队列等。我猜想是基于TCC和基于消息最终一致性2种方案来实现的。下面画个简单的图。

分布式事务GTS学习记录_第3张图片

要想使用分布式事务,首先,依赖相关jar包,主要有Txc-client,Txc-datasource,Txc-resourcemanager,然后在本地创建Txc  client,通过实例化一个TxcTransactionScanner来实现。要传3个参数,应用名,所关联的Txc server的组,事务的模式(标准,人工,重试)。最后,在你要加分布式事务的方法上加注解@TxcTransaction,对业务代码是非侵入的。该事务会创建全局事务xid,该事务下的子事务叫branchId。也就是说,多个子事务branchId交给一个全局事务xid来管理,所有branchid执行成功,全局事务才提交。这里的Txc server相当于两阶段提交的事务协调者,是分布式事务的中枢,Txc client来定义事物的边界,Txc Resourcemanager用来创建,提交,回滚子事物。事务的传递,用到Rpc框架和消息队列。

看了源码,其中用到了一个日志表txc_undo_log,只是个临时表,最终不会记录业务数据。由于所有branchId子事务是实时持久化的,该表记录的是所有子事务操作的回滚sql,当全局事务xid提交时,会物理删除该事务下的日志记录;当全局事务回滚是,会执行该回滚sql并物理删除日志记录。

   

你可能感兴趣的:(分布式事务)