首先看看@EnableTransactionManagement注解源码,发现该注解是导入了TransactionManagementConfigurationSelector组件
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default 2147483647;
}
在看看导入的组件有什么作用
protected String[] selectImports(AdviceMode adviceMode) {
switch(adviceMode) {
case PROXY:
return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
default:
return null;
}
}
导入的组件是根据我们的AdviceMode注解设置再一次来导入一些组件,而AdviceModel属性决定我们事务底层使用的是JDK动态代理还是AspectJ,如果是PROXY则导入AutoProxyRegistrar. 和 ProxyTransactionManagementConfiguration这两个组件,默认是使用JDK动态代理,我认为要理解事务的执行流程,就应该搞懂这两个组件做了什么工作
先看AutoProxyRegistrar,可以看到,该组件大概是用来注册一些bean的
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar
在看
if (mode == AdviceMode.PROXY) {
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean)proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
如果我们在注解中设置了AdviceModel是使用jdk动态代理,就会使用AOP设置工具类的注册一个自动代理创建器
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
进入方法内部,实际上就是调用这个方法
registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
InfrastructureAdvisorAutoProxyCreator有什么作用呢?
就是利用后置处理器机制,在对象创建以后,包装对象,返回一个代理对象(增强器),利用代理对象执行方法利用拦截器链进行调用
bean初始化前
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = this.getCacheKey(beanClass, beanName); //先从缓存(相当于容器吧)中看看有没有这个bean
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
return null;
}
}
bean初始化后进行包装 —> this.wrapIfNecessary(bean, beanName, cacheKey);
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
现在再来看这个组件ProxyTransactionManagementConfiguration
核心方法
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(this.transactionAttributeSource()); //设置事务属性
advisor.setAdvice(this.transactionInterceptor()); //事务拦截器
if (this.enableTx != null) {
advisor.setOrder((Integer)this.enableTx.getNumber("order"));
}
return advisor;
}
先看事务属性的设置
实际上就是解析事务注解中的一些配置的属性
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
分情况。三种事务注解
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
当然我们使用的就是spring的事务注解
点进去看注解解析的方法
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
Propagation propagation = (Propagation)attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = (Isolation)attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
List<RollbackRuleAttribute> rollbackRules = new ArrayList();
Class[] var6 = attributes.getClassArray("rollbackFor");
....
最后,事务核心就是在于这个事务的拦截器上advisor.setAdvice(this.transactionInterceptor());
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor(); // 实例化一个事务拦截器
interceptor.setTransactionAttributeSource(this.transactionAttributeSource()); //设置事务属性
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager); //如果有事务管理器,就加上事务管理器
}
return interceptor;
}
这个事务拦截器实现了方法拦截器的接口
TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor,
所以直接看他重写的invoke方法
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
Method var10001 = invocation.getMethod();
invocation.getClass();
return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed); // 事务处理的核心方法
}
看看这个方法invokeWithinTransaction
TransactionAttributeSource tas = this.getTransactionAttributeSource();
TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null; //获取相关事务属性
PlatformTransactionManager tm = this.determineTransactionManager(txAttr); //设置事务平台管理器
String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);//获取要执行的事务方法
Object result; //方法返回值
如何获取平台事务管理器
this.determineQualifiedTransactionManager(this.beanFactory, qualifier);//如果我们在@Transactional中上有配置,就根据名称获取
defaultTransactionManager = (PlatformTransactionManager)this.beanFactory.getBean(PlatformTransactionManager.class);//否则就从ioc容器中根据类型获取
事务处理核心部分
TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
result = null;
//如果是一个事务方法,就在这里开启事务
try {
result = invocation.proceedWithInvocation(); //事务方法执行
} catch (Throwable var17) {
this.completeTransactionAfterThrowing(txInfo, var17); //如果事务方法出现异常,执行回滚事务
throw var17;
} finally {
this.cleanupTransactionInfo(txInfo);
}
this.commitTransactionAfterReturning(txInfo); //最后提交事务
return result; //方法返回值
事务回滚
try {
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
} catch (TransactionSystemException var6) {
this.logger.error("Application exception overridden by rollback exception", ex);
var6.initApplicationException(ex);
throw var6;
} catch (Error | RuntimeException var7) {
this.logger.error("Application exception overridden by rollback exception", ex);
throw var7;
}
所以整一个事务方法执行流程大概是这样的
在目标方法执行的时候;
- 执行拦截器链;
- 事务拦截器:
- 先获取事务相关的属性
- 再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger最终会从容器中按照类型获取一个PlatformTransactionManager;
- 执行目标方法
如果异常,获取到事务管理器,利用事务管理回滚操作;
如果正常,利用事务管理器,提交事务