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 事务管理机制

下面就以 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 方法上不会报错,但也不会生效。

spring 事务管理机制

spring 事务管理机制

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

上一篇:MyBatis架构设计及源代码分析系列(一):MyBatis架构


下一篇:关于SOA架构设计的案例分析