探寻Spring事务的入口类以及核心主流程
前言
基础知识已经了解完毕,本篇主要讲解下Spring对于事务支持的源码。从入口类到主流程
我们通过一个简单的@Transactional
的注解就完成了对于事务的支持。这里面的内部的构造大家也都知道是通过AOP
的思想来实现的,那么到底是如何处理的,我们来一探究竟。
知识点
事务的处理流程:Aop代理实现 事务处理的入口类:TransactioanIntercepor 事务的核心主流程:事务开启->执行业务流程 ?执行成功:提交事务,执行失败:回滚事务
1.AOP代理流程
Spring对于事务的管理,是用Aop来实现的。通过添加@Transational注解实现 事务的管理通过
TransactionManager
来处理
这里我们可以先通过一张图基于我们目前的知识对spring事务的基本流程有个印象。
TransactionInterceptor
的invoke
方法作为入口执行获取代理对象 开启事务 执行service的业务逻辑 若出现异常则,回滚事务 若执行成功,提交事务
2.Spring事务源码初探
2.1.入口类TransactioanIntercepor
TransactioanIntercepor
会对我们添加了@Transactional
注解的方法或者类进行拦截,之后就会在执行业务逻辑之前先调用该类。我们假设有一个流量充值的功能。代码片段如下:
@Transactional
public void finishRefillData(RefillRequest refillRequest) {
// 完成支付转账
accountAmountService.transfer(refillRequest.getUserAccountId(),
refillRequest.getBusinessAccountId(), refillRequest.getPayAmount());
// 创建充值订单
refillOrderService.add(createRefillOrder(refillRequest));
}
基于上面的代码片段,我们来研究下源码的执行流程。
2.2.执行流程
找到了入口类
TransactioanIntercepor
之后,我们可以找到如下代码
1.TransactioanIntercepor.invoke()
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
//核心业务逻辑
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
这里的targetClass
即为我们注解@Transactional
标注的类RefillDataCenterServiceImpl
,核心的业务逻辑都在invokeWithinTransaction()
方法中
2.TransactionAspectSupport.invokeWithinTransaction
通过类名
xxxAspectxxx
我们可以看出这是一个Aop的代理类。
下面这段逻辑是核心,包含了事务的开启,提交,回滚等。
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
//这里是JTATransactionManager
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
//这里是RefillDataCenterServiceImpl的全限定名
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//事务是在这里开始创建的
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//这里执行我们具体的业务方法,即`RefillDataCenterService.finishRefillData()`
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//如果上面的业务逻辑代码报错了,这里进行事务的回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
//如果没有报错,这里进行事务的提交
commitTransactionAfterReturning(txInfo);
return retVal;
}

1.创建事务: TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);2.执行业务逻辑: invocation.proceedWithInvocation()3.若执行业务失败:回滚事务 completeTransactionAfterThrowing(txInfo, ex)4.若业务执行成功:事务提交 commitTransactionAfterReturning(txInfo)
关于
更多内容可关注公众号
Github: https://github.com/liangliang1259/common-notes 公众号

文章转载自阿亮的日志,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




