下面来了解spring事务实现的几个关键类
PlatformTransactionManager
TransactionDefinition
TransactionStatus
3.1 PlatformTransactionManager是spring事物框架的一个核心接口, 虽然说应用可以直接使用,但是应用一般是通过TransactionTemplate或者通过aop声明式事务方式来使用,下面我们来看一下这个接口的定义
Public interface PlatformTransactionManager{
//返回当前事务,或者开启一个事物
TransactionStatus getTransaction(TransactionDefinition definition);
//事务提交
voidcommit(TransactionStatus status);
//事物回滚
voidrollback(TransactionStatus status);
}
大家应该很容易看出来这个接口的使用方式
1) TransactionStatus status = transactionManager.getTransaction(definition);
根据事物的定义开启或者返回当前事务
2) 执行本地数据库crud操作, 并根据执行结果设置事物状态
3) 根据事物状态回滚或者提交
transactionManager.commit(status);
transactionManager.rollback(status);
3.2 TransactionDefinition
主要定义事务的隔离级别,传播级别,事务超时时间以及是否只读事务
下面我们来看几种事务配置片段:
1) <bean id="test"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事务管理器 -->
<property name="transactionManager" ref="transactionManager" />
<property name="target" ref="testTarget" />
<property name="proxyInterfaces" value="hongwei.quhw.Test" />
<!-- 配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
2) <bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<!-- 配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
3) <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
4) @Transactional(propagation=Propagation.REQUIRED)
public class TestImpl implement Test{
}
无论你能在网上找到的对事务属性的配置方式最终都会转换为TransactionDefinition的实现类,在PlatformTransactionManager事务管理器根据事务定义来开启事物
3.3 TransactionStatus
1) 有前面的描述事务管理器PlatformTransactionManager开启事务的方法getTransaction中获取事务状态对象TransactionStatus,在开启事务方法getTransaction中判断需不需要开启一个新的事务,如果开启新的事务那么isNewTransaction()值为true,如果不开启新的事务isNewTransaction()的值为false
2) 根据执行业务逻辑结果判断是否需要回滚事务,需要回滚调用方法setRollbackOnly(),这样isRollbackOnly()为true, 否则没有调用isRollbackOnly()为false代表不需要回滚
3)(1) 根据isRollbackOnly()值来决定调PlatformTransactionManager的commit或者rollback方法;
(2) 根据isNewTransaction()值,如果为true的代表需要真正执行commit或者rollback操作; 若果为false不做数据库层面的commit或者rollback,做一些业务层面的回调处理。
事物同步管理器
3.4 DatasourceTransactionManager
下面以我们常使用的,基于java数据源标准接口Datasource操作的事物管理器DatasourceTransactionManager为例来具体讲解spring的事务流程。
AbstractPlatformTransactionManager实现了事务管理器接口,定义了事务管理的流程模板封装了事务管理的公共操作
3.4.1获取事务流程getTransaction(definition)
1) 调抽象方法transaction =doGetTransaction(), 获取代表事务的对象,这个方法在DatasourceTransactionManager中会构建一个DataSourceTransactionObject对象并根据数据源Datasource到当前线程获取数据库连接封装对象ConnectionHolder(第一次开启就为null)设置到对象中。
由上描述知道我们获取的事物对象有可能是没有获取数据连接开始事务。
2) 判断如果没传入TransactionDefinition对象的话,构建一个默认的事务定义对象
3) isExistingTransaction(transaction),判读有没有开启数据库链接,事务有没有激活。如果已开启且事务已经激活, 那么根据事务的传播级别处理事务状态一般会构建TransactionStatus对象newTransaction属性设置为false,在通过事务同步器把事务状态同步到当前线程
这里结束流程,返回事务状态
4) 事务超时时间的判断
5) 构建TransactionStatus对象newTransaction属性设置为true
开启事调doBegin方法, 在DatasourceTransactionManager中具体实现为从dataSource获取数据库连接,将数据连接autoCommit设置为false, 激活事务,将connectionHodler连接资源绑定到线程变量中
6) 在过事务同步器把事务状态同步到当前线程
3.4.2 commit(TransactionStatus)
1) 根据事务状态,判断事务是否应经结束
2) 根据事务状态判断是否需要回滚,回滚走回滚流程
3) processCommit(status) 执行事务提交,下面我们先用伪代码示例下:
try {
try {
triggerBeforeCommit(status);
} finally {
triggerBeforeCompletion(status);
}
doCommit(status);
try {
triggerAfterCommit(status);
} finally {
triggerAfterCompletion(status);
}
} finally {
cleanupAfterCompletion(status);
}
doCommit是真正的数据库提交DatasourceTransactionManager中的实现为connection.commit()
在做doCommit前后都提供了回调接口供业务扩展
triggerBeforeCommit做一些像O/R mapping框架的flush操作并不是真正的事务提交
triggerBeforeCompletion在triggerBeforeCommit之后做一些资源清理工作,triggerBeforeCommit抛异常也执行
triggerAfterCommit在事务真正提交之后做一些操作如确认消息发送邮件等等
triggerAfterCompletion无论事务提交成功与否都要做一些资源的清理工作
cleanupAfterCompletion最后对事务同步器做一些清理工作
3.4.3 rollback(status) 回滚事务
1) 根据事务状态,判断事务是否应经结束
2) processRollback(status)执行事务回滚,如下类似伪代码:
try {
triggerBeforeCompletion(status);
doRollback(status);
triggerAfterCompletion(status);
} finally {
cleanupAfterCompletion(status);
}
3.4.4如上事务的提交回滚操作的前后都提供了回调接口,spring通过事务同步器的注册与回调机制来保证业务在事务提交前后插入业务, xts二阶段的实现也利用了这个机制。
TransactionSynchronizationUtils工具类衔接了上面的回调入口和事务同步器管理类TransactionSynchronizationManager
TransactionSynchronizationManager.registerSynchronization方法用来向当前线程注册实现了TransactionSynchronization接口的事务同步器,它定义了一些回调方法业务实现
public interface TransactionSynchronization{
void beforeCommit(boolean readOnly);
void beforeCompletion();
void afterCommit();
void afterCompletion(int status);
……等等
}
自此我们基本介绍了spring事务的内核设计及流程。
我们常用spring事务模板TransactionTemplate就是利用上面介绍的核心类型封装了事务流程,通过TransactionCallback接口专注业务逻辑。
Spring事务的还一大亮点就是它的声明式事务的实现,spring的声明式事务是springaop的一个很好的示例,很多同学在工作很长一段时间都没有业务场景要求他们写一个aop也没有很好的理解清楚springaop的使用场景,不妨看看spring声明式事务的实现,对于spring声明式事务实现springaop原理这里就不在展开了。