spring 事务管理机制

1. spring 事务管理抽象

spring 的事务策略机制的核心就是 org.springframework.transaction.PlatformTransactionManager 接口。

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(
            TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

PlatformTransactionManager 的方法运行出错时,都会抛出 TransactionException 异常,而这个异常几乎都是致命的,不可修复的。

getTransaction(..) 方法会根据对 TransactionDefinition 对象的处理结果返回一个 TransactionStatus 对象。 TransactionStatus 对象则表示一个事务的状态,表示该事务是否是一个新的事务,是否 commit 或 rollback 等。

public interface TransactionStatus extends SavepointManager {

    /**
     * 是新的事务还是已存在的事务
     */
    boolean isNewTransaction();

    /**
     * 是否有 savePoint*/
    boolean hasSavepoint();

    /**
     * Set the transaction rollback-only. */
    void setRollbackOnly();

    /**
     * 该事务是否已标记 rollback-only
     */
    boolean isRollbackOnly();

    /**
     * Flush the underlying session to the datastore, if applicable:
     * for example, all affected Hibernate/JPA sessions.
     */
    void flush();

    /**
     * Return whether this transaction is completed, that is,
     * whether it has already been committed or rolled back.*/
    boolean isCompleted();

}

TransactionDefinition 接口则定义了下面几个属性

  • Isolation 隔离性级别
  • Propagation 传播属性:在事务上下文存在或者不存在时,可以指定方法的 tansaction 行为(新创建,使用已有的还是抛出异常)
  • Timeout: 超时时间
    • 时间单位 s
    • 表示在该时间内如果函数还没有执行完成,就会 rollback
  • Read-only status:  当代码中只是读取数据,而不修改数据时,可以使用该属性。

在和 mybatis 配合时,一般会使用 DataSourceTransactionManager, 它们的继承关系如下:

 

 下面就以 spring-mybatis 给出配置事务的实例

1. 定义 DataSource

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="${jdbc.initialSize}"></property>
        <property name="maxActive" value="${jdbc.maxActive}"></property>
        <property name="maxIdle" value="${jdbc.maxIdle}"></property>
        <property name="minIdle" value="${jdbc.minIdle}"></property>
        <property name="maxWait" value="${jdbc.maxWait}"></property>
    </bean>

2. 定义 DataSourceTransactionManager bean, 此时需要引用前面配置的 DataSource Bean

    <!-- 声明事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

3. 如果是使用基于注解的 spring 声明式事务管理, 需要如下配置

<tx:annotation-driven transaction-manager="transactionManager"/>

2. 声明式事务管理

2.1 对声明式事务管理机制的理解

spring 声明式事务管理是使用 AOP 代理实现的, transaction advice 事务通知是由元数据(注解或者 XML)驱动的。(待完善。。。)

2.2 @Transactional 注解

在上节最后我们已经说明,要使用基于注解的 spring 声明式事务,需要在 xml 中使用 <tx:annotation 配置。

<tx:annotation-driven transaction-manager="transactionManager"/>

<tx:annotation-driven 配置

XML 属性 默认值 描述
transaction-manager
transactionManager
如果声明的transaction manager 名字不是
transactionManager才需要配置
mode proxy 有 proxy, aspectj 两种模式可选
proxy-target-class false

只对 proxy 模式有效。是基于接口的还是基于类的代理被创建。

true,那么基于类的代理将起作用(这时需要cglib库)

false,使用标准的JDK 基于接口的代理

order Ordered.LOWEST_PRECEDENCE

Defines the order of the transaction advice that is applied

to beans annotated with @Transactional.

 

@Transactional 配置

@Transactional 既可以注解在 class 上,也可以注解在 method 上。

有下面几点需要注意

  • 尽量注解在具体实现类中(大部分情况是 service 实现类),注解在接口上也可以,但还需要其他的配置才能生效,此处不会讲述。
  • 在注解到 method 上时,该 method 需要是 public 修饰符修饰,在 proxy 默认模式下,注解在 package或者 private 方法上不会报错,但也不会生效。

 

 

参考链接: https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html#tx-multiple-tx-mgrs-with-attransactional

 

posted @ 2017-11-23 10:36  ReyCG  阅读(321)  评论(0)    收藏  举报