今天我带领大家一起看一下springboot中,事务怎么使用以及源码解析:
springboot事务生效
@EnableTransactionManagement一切的起源
不懂springboot自动装配的可以给我留言,我会讲一下,这里我就不再叙述了,我就当大家都懂了,我们就先从@EnableTransactionManagement这个注解开始一个愉快的旅程:
TransactionManagementConfigurationSelector这个类继承了importSeletor接口(如果想了解importSeletor接口的留言), 默认情况下走PROXY的逻辑:
ProxyTransactionManagementConfiguration主要干了三件事(实现原理AOP):
- 注入BeanFactoryTransactionAttributeSourceAdvisor类,这个类是advisor,继承了 AbstractBeanFactoryPointcutAdvisor,需要提供PointCut和MethodInterceptor.
- 注入AnnotationTransactionAttributeSource主要来获取事务的源信息,底层就是通过解析@Transactional注解
- 注入TransactionInterceptor,这个类主要继承了MethodInterceptor,是事务的关键
我们重点类说BeanFactoryTransactionAttributeSourceAdvisor和TransactionInterceptor
1、先说BeanFactoryTransactionAttributeSourceAdvisor
TransactionAttributeSourcePointcut继承了StaticMethodMatcherPointcut(其实切入点方式有六种)
主要看matches方法:
我们来追溯一下这个getTransactionAttribute方法:到这个
AbstractFallbackTransactionAttributeSource类中,当中有两个抽象方法:
@Nullable
//通过类获取事务信息
protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);
/**
* Subclasses need to implement this to return the transaction attribute for the
* given method, if any.
* @param method the method to retrieve the attribute for
* @return all transaction attribute associated with this method, or {@code null} if none
*/
@Nullable
//通过方法获取事务信息
protected abstract TransactionAttribute findTransactionAttribute(Method method);
这两个方法的实现在AnnotationTransactionAttributeSource,当初ProxyTransactionManagementConfiguration注入的就是这个类,最终我们看到了
SpringTransactionAnnotationParser
进入SpringTransactionAnnotationParser的parseTransactionAnnotation方法:
就是判断从类或方法中的@Transactional注解中拿到的信息是否为null.
2、TransactionInterceptor这个类是事务的主要实现
进去invokeWithinTransaction方法,看主要逻辑
//先获取事务管理器,PlatformTransactionManager是接口,我这里的实现类是DataSourceTransactionManager
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 创建一个TransactionInfo实例
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//调用代理的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
详细看一下这个环绕通知的几个方法
- createTransactionIfNecessary
- completeTransactionAfterThrowing
- cleanupTransactionInfo
- commitTransactionAfterReturning
createTransactionIfNecessary
上述的代码是创建transationinfo的过程,接下来操作都是transationinfo这个对象、
completeTransactionAfterThrowing
cleanupTransactionInfo
commitTransactionAfterReturning
后面我会跟大家来聊一下事务管理器的源码