二Spring事务执行流程
Posted 柠檬时间
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二Spring事务执行流程相关的知识,希望对你有一定的参考价值。
接上节内容,Spring事务执行原理通过创建一个BeanFactoryTransactionAttributeSourceAdvisor,并把TransactionInterceptor注入进去,而TransactionInterceptor实现了Advice接口。而Spring Aop在Spring中会把Advisor中的Advice转换成拦截器链,然后调用。
执行流程
- 获取对应事务属性,也就是获取@Transactional注解上的属性
- 获取TransactionManager,常用的如DataSourceTransactionManager事务管理
- 在目标方法执行前获取事务信息并创建事务
- 回调执行下一个调用链
- 一旦出现异常,尝试异常处理,回滚事务
- 提交事务
具体分析
1. 获取对应事务属性,具体代码执行流程如下:
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
//1. allowPublicMethodsOnly()返回true,只能是公共方法
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 忽略cglib代理,指向当前使用类
Class<?> userClass = ClassUtils.getUserClass(targetClass);
//method代表接口中的方法、specificMethod代表实现类的方法,如果代理类为空,方法不会被执行
Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
//如果我们正在处理带有泛型参数的方法,找到其原始方法
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
//查看方法中是否存在事务
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
//查看方法所在类是否存在事务声明
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
//如果存在接口,则在接口中查找
if (specificMethod != method) {
//查找接口方法
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
//到接口类中寻找
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
getTransactionAttributeSource()获得的对象是在ProxyTransactionManagementConfiguration创建bean时注入的AnnotationTransactionAttributeSource对象。 AnnotationTransactionAttributeSource中getTransactionAttributeSource方法主要逻辑交给了computeTransactionAttribute方法,所以我们直接看computeTransactionAttribute代码实现。
computeTransactionAttribute方法执行的逻辑是:
- 判断是不是只运行公共方法,在AnnotationTransactionAttributeSource构造方法中传入true。若方法不是公共方法,则返回null。
- 得到具体的方法,method方法可能是接口方法或者泛型方法。
- 查看方法上是否存在事务
- 查看方法所在类上是否存在事务
- 查看接口的方法是否存在事务,查看接口上是否存在事务。
所以如果一个方法上用了@Transactional,类上和接口上也用了,以方法上的为主,其次才是类,最后才到接口。
2. 获取TransactionManager,具体代码执行流程如下:
protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
//如果未设置tx属性,请勿尝试查找tx manager
if (txAttr == null || this.beanFactory == null) {
return getTransactionManager();
}
String qualifier = txAttr.getQualifier();
if (StringUtils.hasText(qualifier)) {
return determineQualifiedTransactionManager(qualifier);
}
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
return determineQualifiedTransactionManager(this.transactionManagerBeanName);
}
else {
//常用的会走到这里
PlatformTransactionManager defaultTransactionManager = getTransactionManager();
if (defaultTransactionManager == null) {
defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
//从beanFactory获取PlatformTransactionManager类型的bean
defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
@Bean
public PlatformTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource());
}
以上是关于二Spring事务执行流程的主要内容,如果未能解决你的问题,请参考以下文章