spring4.0事务超详细源码解析
Posted 看写写
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring4.0事务超详细源码解析相关的知识,希望对你有一定的参考价值。
事务
github:https://github.com/Notelzg/spring-reader
目前事务都是基于mysql的事务,其特性是 atomicity(原子性), consistency(一致性), isolation(隔离性), durability(持久性)
ACID四大特性。spring的事务就是在spring中对事务进行适配,通过模板的设计模式来避免 重复的代码,把重复性的开始事务、关闭事务、回滚等重复事情做了,而业务侧值只需要写业务代码
通过注解的方式开启事务就好了。这种方式提高了开发的效率,对事务进行代理对开发透明。 对后续的扩展比较方便。而且如果模板方法有问题,可以统一升级,而且避免了个人写事务导致的错误。
看到这里大家肯定会想到了spring的AOP,像这种重复的,有固定入口的,特别适合切面来做。spring 事务 也是实现了事务的切面增强,基于Spring AOP技术。
开启配置
在配置文件中,通过下面的配置开启对事务的支持。 这个如果你没有开启AOP的配置,这里会默认注册AOP,因为事务是基于AOP做的。
//proxy-target-class 这里是tru,由于基于AOP所以这里指的是AOP的属性,是适应CgLib,还是JDK动态代理
// 为true标识,代理类使用CgLib生成子类进行代理。如果Spring AOP还没有配置,这里会先注册AOP的 beanPost
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
// 这里的false不会生效, 下面不会覆盖上面的(因为false不进行处理,true的时候属性设置为true,上面
//这里是存在冲突的,请注意,可能导致事务失效,
<aop:aspectj-autoproxy proxy-target-class="false"/>
配置激活的beanPost
1, xml命名空间和java类之间的映射 TxNamespaceHandler这个命名空间都是通过配置文件配置的, spring会加载所有的命名空间
spring-tx-4.3.30.RELEASE.jar/META-INF/spring.handlers
文件内容:
http\\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
2, java事务命名空间解析
public class TxNamespaceHandler extends NamespaceHandlerSupport
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
public void init()
this.registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
// 上面配置的属性: annotation-driven 这个激活了这个配置
this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
this.registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
3, 注册事务需要用到的切面 AnnotationDrivenBeanDefinitionParser.java
xml文件解析, annotation-driven
public BeanDefinition parse(Element element, ParserContext parserContext)
this.registerTransactionalEventListenerFactory(parserContext);
String mode = element.getAttribute("mode");
// 这个应该是使用aspectJ的支持,目前我们都没有使用
if ("aspectj".equals(mode))
this.registerTransactionAspect(element, parserContext);
else
// 正常情况下都走的这里
AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
注册 advice, pointCut, 织入 需要的类
// 专门定义了一个内部类来专门处理AOP相关的,也体现了设计模式的开闭原则
private static class AopAutoProxyConfigurer
private AopAutoProxyConfigurer()
public static void configureAutoProxyCreator(Element element, ParserContext parserContext)
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName))
// 对spring 事务注解进行解析, 获取方法/类上面的事务属性,在TransactionAttributeSourcePointcut的时候使用
Object eleSource = parserContext.extractSource(element);
RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(2);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// 事务增强器,实现了advice
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(2);
// 这里设置 transctionManager 类名称, 这里新增属性,key:transactionManagerBeanName,
//value: transactionManager(配置文件里面配置的,transaction-manager:)
AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
// 设置解析事务注解类,这里就可以看出把pointCut 和 事务解析 分离的好处了
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// advisor,里面包含了 advice 和 pointCut
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(2);
// 把事务解析器注入, 这里是RuntimeBeanReference类型, 初始化bean的时候就会去生成该bean的对象
// 这里是因为该类在pointCut静态检查的时候就需要使用,所以先进行初始化
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 把事务增强器注入, 这里是字符串类型,为什么呢,初始化bean的时候不会获取增强器的bean的对象?
// 这里设置成string,是为了延迟初始化增强器,因为增强器是在生成具体的代理的时候才需要生成,并且使用,
// 所以可以延迟加载生成对象,这里也符合spring的哲学,能延迟加载的就延迟加载
// 这里设置拦截器的名称 ,然后通过 父类的getAdvice()方法去获取具体对象
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
if (element.hasAttribute("order"))
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
advisor
org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
该类聚合了切点,和增强器,所以从这里开始分析,由于其实现了Advisor接口
所以BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans
所以BeanFactoryAdvisorRetrievalHelper是在AOP里面自动开启的,具体细节可以看AOP解析。
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 检查该类实现的所有接口,包含该类
检查所有方法,是否需要进行增强。
可以获取到事务的切面。
// 继承了 AbstractBeanFactoryPointcutAdvisor 有默认实现 getAdvice,只要设置adviceBeanName即可
// 在注册bena的时候,已经设置了adviceBeanName, 其类是:TransactionInterceptor.java
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor
private TransactionAttributeSource transactionAttributeSource;
//切点,这个类是一个abstract, getTransactionAttributeSource 是子类实现,提供具体的解析,
// TransactionAttributeSourcePointcut 提供整体的流程处理, 可以看做是一个模板类,处理统一的流程
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut()
@Override
protected TransactionAttributeSource getTransactionAttributeSource()
return transactionAttributeSource;
;
/**
* Set the transaction attribute source which is used to find transaction
* attributes. This should usually be identical to the source reference
* set on the transaction interceptor itself.
* @see TransactionInterceptor#setTransactionAttributeSource
*/
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource)
this.transactionAttributeSource = transactionAttributeSource;
/**
* Set the @link ClassFilter to use for this pointcut.
* Default is @link ClassFilter#TRUE.
*/
public void setClassFilter(ClassFilter classFilter)
this.pointcut.setClassFilter(classFilter);
// 获取切点, 对类,方法
@Override
public Pointcut getPointcut()
return this.pointcut;
切点
org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable
// 个人任务这里包装一层,把pointCut和 TransactionAttributeSource解析组合起来,方便后续的扩展, 同时也是
// 降低了耦合度,复杂度,方便维护和扩展
@Override
public boolean matches(Method method, Class<?> targetClass)
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass))
return false;
// 子类实现该方法, 通过 AopAutoProxyConfigurer类,我们知道这里的source是
// org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
// 改属性正常情况下都不能为空,如果为空有问题了,事务属性解析不为空,则标识是事务,需要增强
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
// 子类实现这个方法,提供具体的注解解析实现,
protected abstract TransactionAttributeSource getTransactionAttributeSource();
事务解析的整体流程
抽象父类,处理整理流程
Fallback 为什么有FallBack是因为解析属性的时候,会有很多倒退的操作
来保证能处理大部分的情况。
public abstract class AbstractFallbackTransactionAttributeSource implements TransactionAttributeSource
// 获取事务的属性
@Override
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass)
// object类肯定不是,直接结束
if (method.getDeclaringClass() == Object.class)
return null;
// First, see if we have a cached value.
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null)
// Value will either be canonical value indicating there is no transaction attribute,
// or an actual transaction attribute.
if (cached == NULL_TRANSACTION_ATTRIBUTE)
return null;
else
return cached;
else
// 解析细节
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// Put it in the cache.
if (txAttr == null)
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
else
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute)
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
if (logger.isDebugEnabled())
logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
this.attributeCache.put(cacheKey, txAttr);
return txAttr;
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass)
// 公共方法检查,非公共方法直接结束
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers()))
return null;
// 如果是cglib生成的代理,则获取其父类
Class<?> userClass = ClassUtils.getUserClass(targetClass);
// 如果method 是来自接口的,则返回 userClass中的method,返回实现类中的method
Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
// If we are dealing with method with generic parameters, find the original method.
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
// First try is the method in the target class.
// 调用子类的具体实现,这里是子类进行扩展, 比如对TranactionL 注解的解析,如果方法上解析成功,直接返回
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null)
return txAttr;
// Second try is the transaction attribute on the target class.
// 方法上面没有,则进行类上面检查,同样是子类实现,比如注解解析
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method))
return txAttr;
// 倒退操作,尽可能的把事务解析出来
if (specificMethod != method)
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null)
return txAttr;
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method))
return txAttr;
return null;
protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);
protected abstract TransactionAttribute findTransactionAttribute(Method method);
protected boolean allowPublicMethodsOnly() return false;
事务注解解析入口
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
这里的具体解析是通过父类(AbstractFallbackTransactionAttributeSource)进行的,该类实现了父类的方法,进行扩展
// 注解解析类,继承一个抽象模板类,这个也是属于sprig的特色了,把统一处理的流程放在抽象类中,把经常变动/扩展的部分作为
// 抽象方法进行(封装变化), 达到开闭原则
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable
// 只支持 public方法上面的 事务注解
private final boolean publicMethodsOnly;
// 注解解析类
private final Set<TransactionAnnotationParser> annotationParsers;
public AnnotationTransactionAttributeSource()
this(true);
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly)
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet(4);
// 默认支持 spring 事务解析, 目前事务注解都是走的这里
this.annotationParsers.add(new SpringTransactionAnnotationParser());
protected TransactionAttribute findTransactionAttribute(Class<?> clazz)
return this.determineTransactionAttribute(clazz);
// 这两个方法 返回值、方法名称一样,入参不一样,属于静态的多态
protected TransactionAttribute findTransactionAttribute(Method method)
return this.determineTransactionAttribute(method);
// 解析类、方法上面的注解
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element)
if (element.getAnnotations().length > 0)
// 解析的类可能存在多个,所以是循环
Iterator var2 = this.annotationParsers.iterator();
while(var2.hasNext())
TransactionAnnotationParser annotationParser = (TransactionAnnotationParser)var2.next();
// 开始机械
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
// 解析就快速结束
if (attr != null)
return attr;
return null;
protected boolean allowPublicMethodsOnly()
return this.publicMethodsOnly;
事务注解解析器
一个接口,一个实现类,面向接口编程
比较符合先设计,再实现。spring这个模式非常的好。但是工作中有的时候很难做到
这种方法确实是和扩展。同时发现spring中类名起的都很好,形容词 名称 动词
每次自己起名字是真的难
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable
@Override
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element)
// 获取事务注解的所有属性
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(
element, Transactional.class);
// 解析
if (attributes != null)
return parseTransactionAnnotation(attributes);
else
return null;
// 从这里就可以知道,spring 事务注解支持哪些配置
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes)
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
// 传播范围
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
// 隔离级别
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<RollbackRuleAttribute>();
// 什么异常进行回滚
for (Class<?> rbRule : attributes.getClassArray("rollbackFor"))
rollbackRules.add(new RollbackRuleAttribute(rbRule));
// 什么类回滚
for (String rbRule : attributes.getStringArray("rollbackForClassName"))
rollbackRules.add(new RollbackRuleAttribute(rbRule));
// 哪些类不需要回滚
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor"))
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
// 哪些类名不需要回滚
for (String rbRule : attributes.getStringArray("noRollbackForClassName"))
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
rbta.setRollbackRules(rollbackRules);
return rbta;
增强器
package org.springframework.transaction.interceptor;
TransactionInterceptor.java
就是具体的事务增强器
增强器对象的获取
package org.springframework.aop.support;
public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware
private String adviceBeanName;
// transient 序列化的时候,不进行序列化
// volatile 关键字是可见性,不加可以吗?
// 其实这里可以不加这关键字,因为单例本身是做了检查的,可以保证对象只创建一次, 加上就可以不用每次都走单例的流程,
// 在这里就可以直接解决了,加快是了速度,所以这里加这个关键字主要是为了单例对象使用(大部分都是单例)
// 而原始对象由于初始化的是有 synchronized关键字,所以可以保证其有序性、原子性
private transient volatile Advice advice;
// transient 序列化的时候,不进行序列化
// 没有明白这里使用 volatile关键字的作用,由于这个对象会暴露出去,同时可以被重置,所以
// 需要加上 volatile 关键字,保证其可见性
private transient volatile Object adviceMonitor = new Object();
// org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor
// 继承了该类, 同时设置了adviceBeanName, TransactionInterceptor
public void setAdviceBeanName(String adviceBeanName)
this.adviceBeanName = adviceBeanName;
@Override
public Advice getAdvice()
// 单例,已经实例化的直接返回
Advice advice = this.advice;
if (advice != null || this.adviceBeanName == null)
return advice;
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
if (this.beanFactory.isSingleton(this.adviceBeanName))
// 直接通过容器初始化增强器,由于增强器beanDefinition 在xml解析阶段已经注册,所以这里通过beanName可以完成bean的对象的
// 初始化
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
else
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
// 对于非单利的,也要进行单利处理,springAOP只能使用单利,因为如果使用非单例,将会生成n个对象
// 对内存造成非常大的浪费,如果有1000个类,则要生成1000个对象,完成没有必要,所以切面本身要线程
// 安全,因为切面通过锁巧妙的实现了单例
synchronized (this.adviceMonitor)
if (this.advice == null)
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
return this.advice;
增强器对象的具体实现细节
这里是
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable
public TransactionInterceptor()
@Override
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);
// 调用父类的方法, 通过回调方法,进行扩展
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback()
@Override
public Object proceedWithInvocation() throws Throwable
return invocation.proceed();
);
事务操作整体流程
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean
/**
* Key to use to store the default transaction manager.
*/
private static final Object DEFAULT_TRANSACTION_MANAGER_KEY = new Object();
// 事务信息,放到这里,进行方法调用的时候进行传播
private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
new NamedThreadLocal<TransactionInfo>("Current aspect-driven transaction");
// bean的两个属性,bean初始化的时候必须设置,否则会报错,后面会检查
private PlatformTransactionManager transactionManager;
private TransactionAttributeSource transactionAttributeSource;
// spring 事务处理的主流程
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
throws Throwable
// 解析事务属性
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
// 获取事务管理器,根据配置文件中配置的事务管理beanId, 从spring容器中生成事务管理器bean(bean也在配置文件中配置了)
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 增强方法标识, com.lzg.note.aop.TestA.insert(包名+类名+方法名)
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// true 走这里
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager))
// Standard transaction demarcation with getTransaction and commit/rollback calls.
// 生成事务如果需要的,根据事务的传播行为
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
try
// 回调处理,继续走其他的切面增强,和目标方法
retVal = invocation.proceedWithInvocation();
catch (Throwable ex)
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
finally
// 清除事务相关的数据, 主要是thradLocal中的,同时会恢复之前被挂起的事务(如果之前有挂起的事务的话)
cleanupTransactionInfo(txInfo);
// 目标方法处理完成,处理完成,事务提交,或者回滚, 最后会进行 resume, 如果之前进行过suspend操作的话
commitTransactionAfterReturning(txInfo);
return retVal;
else // 非核心代码删除
/**
* 获取事务管理器,根据配置
*/
protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr)
// Do not attempt to lookup tx manager if no tx attributes are set
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 //删除非核心代码
private PlatformTransactionManager determineQualifiedTransactionManager (String qualifier)
PlatformTransactionManager txManager = this.transactionManagerCache.get(qualifier);
if (txManager == null)
// 从容器中获取
txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
this.beanFactory, PlatformTransactionManager.class, qualifier);
this.transactionManagerCache.putIfAbsent(qualifier, txManager);
return txManager;
// 根据传播机制,进行生成/取出/挂起已有的事务
protected TransactionInfo createTransactionIfNecessary (
PlatformTransactionManager tm, TransactionAttribute txAttr,
final String joinpointIdentification)
TransactionStatus status = null;
if (txAttr != null)
if (tm != null)
// 根据传播机制,进行生成/取出/挂起已有的事务
status = tm.getTransaction(txAttr);
// 包装事务状态到事务信息中, txInfo
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
protected TransactionInfo prepareTransactionInfo (PlatformTransactionManager tm,
TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus
status)
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
// The transaction manager will flag an error if an incompatible tx already exists.
txInfo.newTransactionStatus(status);
// 设置到threadLocal, 同时如果已经有txInfo存在,则把上一个保存到oldTxInfo字段中,后续resumer的时候会用到
txInfo.bindToThread();
return txInfo;
/**
* Execute after successful completion of call, but not after an exception was handled.
* Do nothing if we didn't create a transaction.
* @param txInfo information about the current transaction
*/
protected void commitTransactionAfterReturning (TransactionInfo txInfo)
if (txInfo != null && txInfo.hasTransaction())
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
/**
* Handle a throwable, completing the transaction.
* We may commit or roll back, depending on the configuration.
* @param txInfo information about the current transaction
* @param ex throwable encountered
*/
protected void completeTransactionAfterThrowing (TransactionInfo txInfo, Throwable ex)
if (txInfo != null && txInfo.hasTransaction())
if (logger.isTraceEnabled())
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
if (txInfo.transactionAttribute.rollbackOn(ex))
try
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
catch (TransactionSystemException ex2)
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
catch (RuntimeException ex2)
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
catch (Error err)
logger.error("Application exception overridden by rollback error", ex);
throw err;
else spring4.0事务超详细源码解析