1. 介绍

之前了解过一些分布式事务处理的思想,包括MVCC、TCC等。但是对具体实现的规范和约束还不够理解清晰。本文从事务模型分类来讨论常见的事务模型。事务模型的含义,应该指的是我们如何去使用可控制事务。

首先通过以下一张PPT简单回顾下什么是事务:

2 本地事务模型

本地事务模型:不用事务的编程框架来管理事务,直接使用资源管理器来控制事务。典型的就是java.sql.Connection 中的 setAutoCommit、commit、rollback方法,见下面一段代码,直接使用资源管理器进行事务控制

    Connection conn = getConnection();
        conn.setAutoCommit(false);
        // do something
        boolean success = doSomething();
        if (success) {
            conn.commit();
        } else {
            conn.rollback();
        }

3 编程式事务模型(JTA)

编程式事务模型:就是使用java提供的事务api JTA(Java Transaction API)

和事务服务提供者(一般是指j2ee容器) 进行事务控制,JTA里面提供了 java.transaction.UserTransaction ,里面定义了下面几个方法

begin:开启一个事务
commit:提交当前事务
rollback:回滚当前事务
setRollbackOnly:把当前事务标记为回滚
setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务
getStatus;

不过JTA只是提供了一个接口,并没有提供具体的实现,而是由j2ee服务器提供商 根据JTS规范提供的。下面一段代码演示了如何使用事务JPA:

        InitialContext ctx = new InitialContext();
        UserTransaction ut = (UserTransaction)
    ctx.lookup("javax.transaction.UserTransaction");

        ut.begin();
        //do something
        boolean isSuccess = doSomething() ;

        if(isSuccess){
            ut.commit();
        }else{
            ut.rollback();
        }

JPA规范里面定义了事务相关的几个角色:

  1. 事务上下文:事务状态和属性信息
  2. 资源管理器:数据库连接、JMS连接
  3. 通信管理器:用在分布式事务里面
  4. 应用程序:使用事务服务的程序
  5. 事务管理器:应用程序和事务服务提供者的api接口
  6. 事务服务提供者:实现了JTA规范的J2EE容器

这个是java里面JPA的规范,但是也有一些编程框架提供了自己的编程事务模型,例如java里最常用的就是spring的事务管理器,下面是spring提供的编程接口:org.springframework.transaction.PlatformTransactionManager,这里面就只有三个方法:

getTransaction:根据属性信息决定是否开启事务(具体可以看上一篇文章里面的事务特性小结里面的事务传播属性)

commit;提交当前事务

rollback;回滚当前事务

我们发现其实和JPA提供的编程模型很像,就是开启一个事务,提交还是回滚事务。spring提供的事务编程框架也比较简单

ApplicationContext context = getApplicationContext();
        TransactionTemplate transactionTemplate = (TransactionTemplate)context.getBean("TransactionTemplate");

        transactionTemplate.execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus status) {
                boolean isSuccess = doSomething() ;

                if(isSuccess){

                }else{
                    status.setRollbackOnly();
                }
                return isSuccess;
            }    
        });

4 声明式编程(JTA的变种)

声明式编程:这种编程模型不采用硬编码的方式,而是采用在xml里面进行配置的方式或者使用anotation的方式进行。例如srping里面可以通过aop进行实现。当然本质上也是属于JPA事务的。只不过对其做了一些分装。

 <bean id="accountService"
class="org.springframework.transaction.interceptor. TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/> 
<property name="target" ref="accountServiceTarget"/>
<property name="transactionAttributes">
<props>

  <prop key="*">PROPAGATION_SUPPORTS</prop> 
  <prop key="update*">PROPAGATION_REQUIRED </prop>
</props> 
</property>

5. DTP事务模型

X/Open Distributed Transaction Processing (DTP) 事务模型实现了XA接口。XA事务指的是实现了XA接口符合DTP事务模型的事务。
DTP事务模型是X/Open 这个组织定义的一套分布式事务的标准,也就是了定义了规范和API接口,由这个厂商进行具体的实现。
DTP事务模型主要用于分布式事务

XA接口规范定义了以下几个组件:

  1. 应用程序(AP):也就是应用程序,可以理解为使用DTP的程序 2.资源管理器(RM):资源管理器,这里可以理解为一个DBMS系统,或者消息服务器管理系统,应用程序通过资源管理器对资源进行控制。资源必须实现XA定义的接口 3.事务管理器(TM):事务管理器,负责协调和管理事务,提供给AP应用程序编程接口以及管理资源管理器

AP、RM、TM三者直接互相的协作关系用下图表示:


可以看到,其中TM 和 RM 通过XA接口进行双向通信。AP和TM、RM的通信接口规范没有约定,可以自己实现。

DTP定义的事务概念:

  1. 事务:一个事务是一个完整的工作单元,由多个独立的计算任务组成,这多个任务在逻辑上是原子的。
  2. 全局事务:对于一次性操作多个资源管理器的事务,就是全局事务
  3. 分支事务:在全局事务中,某一个资源管理器有自己独立的任务,这些任务的集合作为这个资源管理器的分支任务
  4. 控制线程:用来表示一个工作线程,主要是关联AP,TM,RM三者的一个线程,也就是事务上下文环境。简单的说,就是需要标识一个全局事务以及分支事务的关系。

    很多数据库都实现了DTP事务模型,用于支持分布式事务。

5.1 两阶段提交(2PC)

两阶段提交是DTP事务模型的一种实现方式。一个TM控制多个RM,协调资源。

两阶段主要指的是:
第一阶段(准备阶段):事务管理器通知资源管理器准备分支事务,资源管理器告之事务管理器准备结果
第二阶段(提交阶段):事务管理器通知资源管理器提交分支事务,资源管理器告之事务管理器结果

5.2 TCC

TCC是一种基于事务补偿(属于事后控制的策略,进行回滚)的模式,注意区别2PC

TCC的执行过程

6 跨域的DTP模型

需要RPC调用,有一些额外的问题。需要引入通信资源管理器。具体看下图:

参考资料:
http://www.cnblogs.com/aigongsi/archive/2012/10/09/2717372.html
http://www.cnblogs.com/lyhabc/p/4902341.html
http://wenku.baidu.com/view/be946bec0975f46527d3e104.html