1.@EnableTransactionManagement注解
可以看出,该注解作用就是向spring容器中添加两个Bean:(1)AutoProxyRegistrar;
AutoProxyRegistrar只有一个方法registerBeanDefinitions,该方法的目的就是注册一个InfrastructureAdvisorAutoProxyCreator,该类又继承了AbstractAdvisorAutoProxyCreator,所以这个类的作用就是开启动态代理,相当于一个BeanPostProcessor,在初始化后会去寻找Advisor类型的Bean,并判断当前某个Bean是否有匹配的Advisor,是否需要利用动态代理产生一个对象。相对应的源码如下:
(2)ProxyTransactionManagementConfiguration
已经知道,spring事务是通过AOP动态代理实现的,而ProxyTransactionManagementConfiguration的作用就是产生一个Advisor,Advisor中的TransactionAttributeSource相当于PointCut,用来判断@Transactional注解;TransactionInterceptor就是代理逻辑,当判断存在@Transactional注解,就会产生一个代理对象作为Bean,代理对象在执行某个方法时,最终就会进入到TransactionInterceptor中的invoke()方法。
下面开始展开对spring事务源码的分析,即TransactionInterceptor中的invoke()方法:
demo
@Transactional注解的默认传播机制是REQUIRED,即没有事务则创建一个新事务,有事务则在当前事务中执行。
1.调用invokeWithinTransaction创建事务
2.protected Object invokeWithinTransaction(Method method, @Nullable Class> targetClass,
final InvocationCallback invocation) throws Throwable {
// TransactionAttribute就是@Transactional中的配置
TransactionAttributeSource tas = getTransactionAttributeSource();
// 获取@Transactional中的属性值,该值必不为空,因为存在默认值
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 返回Spring容器中类型为TransactionManager的Bean对象
final TransactionManager tm = determineTransactionManager(txAttr);
// 将TransactionManager强制转换成PlatFormTransactionManager
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 获取当前在执行的方法的名字
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 创建事务,获取被挂起的事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 执行被代理对象中的方法
retVal = invocation.proceedWithInvocation(); //test
}catch (Throwable ex) {
// 如果抛异常,则进行回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}finally {
cleanupTransactionInfo(txInfo);
}
// 提交事务,具体看第7步
commitTransactionAfterReturning(txInfo);
}
3.protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
TransactionStatus status = null;
// 获取事务(重要方法),AbstractPlatFormTransactionManager
status = tm.getTransaction(txAttr);
// 返回一个TransactionInfo对象,表示得到了一个事务,可能是新创建的一个事务,也可能是拿到的已有的事务
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
4.public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// 得到一个新的DataSourceTransactionObject对象,
// 此时并没有创建数据库连接ConnectionHolder
// new DataSourceTransactionObject txObject
// txObject中的ConnectionHolder置为false
Object transaction = doGetTransaction();
// 调通test方法时,该事务是不存在的,即没有开启过事务
// 在第五步中的doBegin()方法里已经对transaction进行了更改,那么在调用a方法时,已经存在了事务
if (isExistingTransaction(transaction)) {
return handleExistingTransaction(def, transaction, debugEnabled);
}
// 当前Thread中没有事务时,这三个传播机制是等价的
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 调用test时,一开始既然还没开启事务,这里是不会存在挂起对象的,这一步我觉得没什么意义
// suspend方法中会去判断ThreadLocal> synchronizations
// synchronizations是在下面的开启事务方法中的prepareSynchronization中的initSynchronization对ThreadLocal变量赋值
SuspendedResourcesHolder suspendedResources = suspend(null);
// 开启事务,创建数据库连接
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
}
5./**
* Start a new transaction.
*/
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
// 开启事务
// 1.创建数据库连接con;2.将txObject.ConnectionHolder置为true,并且与数据源dataSource绑定
// 3.将txObject的ConnectionHolder中的TransactionActive属性置为true
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
6.private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
// 根据不同的传播级别,判断是否需要创建新的事务
// 1.Propagation.NOT_SUPPORTED:挂起当前事务,但是不开启新的连接
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
// 把当前事务挂起,其中就会把数据库连接对象从ThreadLocal中移除
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
// 2.Propagation.REQUIRES_NEW:挂起当前事务并开启新的连接
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
SuspendedResourcesHolder suspendedResources = suspend(transaction);
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
}
7.public final void commit(TransactionStatus status) throws TransactionException {
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus, false);
return;
}
// 判断此事务在之前是否设置了需要回滚,跟globalRollbackOnParticipationFailure有关
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
processRollback(defStatus, true);
return;
}
// 提交事务,最后会恢复被挂起的资源
processCommit(defStatus);
}