9.Spring事务原理之@EnableTransactionManagement
Spring提供的AOP功能有两种实现方式,可选值有PROXY 和 ASPECTJ,默认值为AdviceMode.PROXY。
一种是Spring自带的AOP功能,主要靠JDK代理和CGLIB代理实现,另外一种是通过第三方框架ASPECTJ实现。
@EnableTransactionManagement中的mode选项就是设定Spring用哪种方式提供AOP功能。
AdviceMode.PROXY表示用Spring自带的AOP功能,AdviceMode.ASPECTJ表示使用ASPECTJ提供AOP功能。
需要注意的是Spring自带的AOP功能不支持本地调用的代理功能,也就是说同一个类中的方法互相调用不会“触发”代理方法。
如果想让自调用触发代理,可以考虑使用ASPECTJ。
由于AdviceMode.PROXY应用比较广泛,而AdviceMode.ASPECTJ应用较少。所以我们主要是讲AdviceMode.PROXY。
参考:www.cnblogs.com/54chensongx…
@EnableTransactionManagement
/***
@EnableTransactionManagement注解有以下几个属性
proxyTargetClass属性:
指定事务的AOP是通过JDK动态代理实现,还是CGLIB动态代理实现。
true的话是CGLIB,false的话是JDK动态代理需要注意的是这个属性只有在AdviceMode设置成AdviceMode.PROXY的情况下才会生效。
假如使用ASPECTJ的AOP框架的话,这个属性就失效了。
另外,这个属性的设定可能会影响其他需要动态代理的类。
比如说将这个属性设置成true,@Async注解的方法也会使用CGLIB生成代理类。
但是总的来说,这个属性的设置不会造成什么负面影响,毕竟JDK动态代理和CGLIB动态代理都能实现我们的需求
mode属性:
Spring提供的AOP功能有两种实现方式,一种是Spring自带的AOP功能,主要靠JDK代理和CGLIB代理实现,另外一种是通过第三方框架ASPECTJ实现。
这个选项就是设定Spring用哪种方式提供AOP功能。AdviceMode.PROXY表示用Spring自带的AOP功能,AdviceMode.ASPECTJ表示使用ASPECTJ提供AOP功能。
需要注意的是Spring自带的AOP功能不支持本地调用的代理功能,也就是说同一个类中的方法互相调用不会“触发”代理方法。如果想让自调用触发代理,可以考虑使用ASPECTJ。
order属性:表示当一个连接点(方法)被切多次时(也就是说有多个Advice和连接点关联),这些连接点的执行顺序。
***/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
//true:cglib false:jdk
boolean proxyTargetClass() default false;
//默认是AdviceMode.PROXY
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
public enum AdviceMode {
/**
* JDK proxy-based advice.
*/
PROXY,
/**
* AspectJ weaving-based advice.
*/
ASPECTJ
}
TransactionManagementConfigurationSelector
注意是1个Selector
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
//这里的AdviceMode 由
//AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
//就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
switch (adviceMode) {
case PROXY:
//如果是 PROXY 那么返回的是
//AutoProxyRegistrar和ProxyTransactionManagementConfiguration
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
//如果是 ASPECTJ 那么返回的是
/**
如果类加载器有"javax.transaction.Transactional"
那么创建AspectJJtaTransactionManagementConfiguration
否则创建AspectJTransactionManagementConfiguration
*/
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
//省略代码
}
TransactionManagementConfigurationSelector继承自AdviceModeImportSelector
所以这个代码
selector.selectImports(currentSourceClass.getMetadata());
进入的是
AdviceModeImportSelector#selectImports(AnnotationMetadata importingClassMetadata)
public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {
public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";
protected String getAdviceModeAttributeName() {
return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
}
@Override
public final String[] selectImports(AnnotationMetadata
importingClassMetadata) {
Class<?> annType = GenericTypeResolver.resolveTypeArgument
(getClass(), AdviceModeImportSelector.class);
/***
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement
@ComponentScan("transaction")
public class BeanConfig {
}
因为TransactionManagementConfigurationSelector
是被@EnableTransactionManagement导入的
@EnableTransactionManagement加在了BeanConfig上面
所以读取的metadata是BeanConfig上面的注解元数据
元数据:是3个注解的值
0 = EnableAspectJAutoProxy
(proxyTargetClass=false, exposeProxy=false)"
1 = EnableTransactionManagement
(mode=PROXY, order=2147483647, proxyTargetClass=false)"
2 = ComponentScan
(scopeResolver=class org.springframework.context.annotation.AnnotationScopeMetadataResolver, lazyInit=false, resourcePattern=**.class, useDefaultFilters=true, excludeFilters=[], scopedProxy=DEFAULT, basePackageClasses=[], nameGenerator=interface org.springframework.beans.factory.support.BeanNameGenerator, basePackages=[], value=[], includeFilters=[])"
*/
AnnotationAttributes attributes =
AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (attributes == null) {
throw new IllegalArgumentException();
}
//这里的adviceMode
//由AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
//就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
//调用TransactionManagementConfigurationSelector.selectImports导入组件
String[] imports = selectImports(adviceMode);
if (imports == null) {
throw new IllegalArgumentException
("Unknown AdviceMode: " + adviceMode);
}
return imports;
}
@Nullable
protected abstract String[] selectImports(AdviceMode adviceMode);
}
调用TransactionManagementConfigurationSelector.selectImports
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
//这里的AdviceMode
//由AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
//就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
switch (adviceMode) {
case PROXY:
//如果是PROXY 那么返回的是
//AutoProxyRegistrar和ProxyTransactionManagementConfiguration
return new String[] {
AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
//如果是 ASPECTJ 那么返回的是
/**
如果类加载器有"javax.transaction.Transactional"
那么创建AspectJJtaTransactionManagementConfiguration
否则创建AspectJTransactionManagementConfiguration
JtaTransaction和Transaction
*/
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
可以看到,如果是Proxy代理的话,会往spring ioc容器注入两个组件如下
AutoProxyRegistrar.class和ProxyTransactionManagementConfiguration.class
AutoProxyRegistrar
而AutoProxyRegistrar又是个BeanDefinitionRegistrar,所以它又给容器导入了一些组件
这个BeanDefinitionRegistrar也是往容器注入组件的工具,看看它的registerBeanDefinitions方法
又注入了什么组件?
模式1:Proxy
导入:AutoProxyRegistrar
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}
解析mode和proxyTagetClass
注入InfrastructureAdvisorAutoProxyCreator
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());
//importingClassMetadata是beanConfig上的注解集合
@Override
public void registerBeanDefinitions(AnnotationMetadata
importingClassMetadata,
BeanDefinitionRegistry registry) {
boolean candidateFound = false;
Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
for (String annType : annTypes) {
AnnotationAttributes candidate =
AnnotationConfigUtils.attributesFor
(importingClassMetadata, annType);
if (candidate == null) {
continue;
}
//默认是PROXY
Object mode = candidate.get("mode");
//默认是false
Object proxyTargetClass = candidate.get("proxyTargetClass");
if (mode != null &&
proxyTargetClass != null &&
AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
//注意:
//切面注册的是AnnotationAwareAspectJAutoProxyCreator
//事务会注入InfrastructureAdvisorAutoProxyCreator
//如果事务和切面同时存在使用AnnotationAwareAspectJAutoProxyCreator
//主要就是判断是否存在名为internalAutoProxyCreator的bean
//如果不存在就注入AnnotationAwareAspectJAutoProxyCreator
//如果存在就判断当前注入的bean权重和已经注入的bean的权重
//如果当前注入的bean的权重大于已经注入的bean的权重
//则注入当前bean
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils
.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
}
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary
(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
//注意这里写死的是InfrastructureAdvisorAutoProxyCreator
return registerOrEscalateApcAsRequired
(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
注册InfrastructureAdvisorAutoProxyCreator
InfrastructureAdvisorAutoProxyCreator继承SmartInstantiationAwareBeanPostProcessor也就是一个BeanPostProcessor。
继承了AbstractAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator重写了BeanPostProcessor的postProcessAfterInitialization。
postProcessAfterInitialization方法的主要的作用
1.在代理寻找候选Advisor时,会调用
InfrastructureAdvisorAutoProxyCreator#isEligibleAdvisorBean
判断是否是合适的AdvisorBean
主要是判断advisorName的角色是否是ROLE_INFRASTRUCTURE=2
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
其实就是为了让ProxyTransactionManagementConfiguration注册的BeanFactoryTransactionAttributeSourceAdvisor能被加入到候选的Advisor中。
//继续注入InfrastructureAdvisorAutoProxyCreator
//注意:切面注册的是AnnotationAwareAspectJAutoProxyCreator
//事务会注入InfrastructureAdvisorAutoProxyCreator
//如果事务和切面都有 注入得是AnnotationAwareAspectJAutoProxyCreator
//区别在于 2个类的isEligibleAdvisorBean方法
//AnnotationAwareAspectJAutoProxyCreator是直接返回true
//InfrastructureAdvisorAutoProxyCreator是判断了
this.beanFactory.getBeanDefinition(beanName).getRole() ==
BeanDefinition.ROLE_INFRASTRUCTURE
2.生成代理类
public class InfrastructureAdvisorAutoProxyCreator extends
AbstractAdvisorAutoProxyCreator {
@Nullable
private ConfigurableListableBeanFactory beanFactory;
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
this.beanFactory = beanFactory;
}
/***
* 在做代理时 判断是否是合适的候选Advisor类
* AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
*/
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
/****
这个条件是寻找AVISOR的Role是 ROLE_INFRASTRUCTURE
比如 BeanFactoryTransactionAttributeSourceAdvisor
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {}
*/
return (this.beanFactory != null &&
this.beanFactory
.containsBeanDefinition(beanName) &&
//判断getRole() == BeanDefinition.ROLE_INFRASTRUCTURE
this.beanFactory
.getBeanDefinition(beanName)
.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}
}
导入:ProxyTransactionManagementConfiguration
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends
AbstractTransactionManagementConfiguration {
/**
使用@Bean注入事务增强器(Advisor)
在事务类创建的时候,被AutoProxyRegistrar导入的组件
InfrastructureAdvisorAutoProxyCreator拦截,
InfrastructureAdvisorAutoProxyCreator拦截的逻辑就是增强事务类的事务方法
而BeanFactoryTransactionAttributeSourceAdvisor作为增强器。
需要把类中所有的方法与需要增强的方法(这里是指被@Transactional标记的方法)进行匹配
匹配成功的增强器
最后会转成拦截器(MethodInterceptor,就是下面的TransactionInterceptor)
然后与目标方法一起在拦截器链中被执行,达到方法增强的效果;
BeanFactoryTransactionAttributeSourceAdvisor的继承关系如下:
--Advisor 顶级接口
--PointcutAdvisor
--AbstractPointcutAdvisor
--AbstractBeanFactoryPointcutAdvisor
--BeanFactoryTransactionAttributeSourceAdvisor
AOP中AspectJPointcutAdvisor的继承关系如下,与AbstractPointcutAdvisor一样,都实现了 --Advisor
--PointcutAdvisor
--AspectJPointcutAdvisor
*/
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
//主要看它的getPointCut方法
//会创建1个methodMatcher
//根据methodMatcher判断方法是否需要匹配被应用事务
BeanFactoryTransactionAttributeSourceAdvisor advisor
= new BeanFactoryTransactionAttributeSourceAdvisor();
//注入解析器
//判断是否canApply的时候会用上
//会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
advisor.setTransactionAttributeSource(transactionAttributeSource());
//transactionInterceptor()返回1个transactionInterceptor
//有2个用处:
//1.在getInterceptorsAndDynamicInterceptionAdvice方法
//将BeanFactoryTransactionAttributeSourceAdvisor转换为对应的interceptor
//2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器
//具体看transactionInteceptor的invoke方法
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
/***
使用@Bean注入 AnnotationTransactionAttributeSource
主要注入2个@Transactional注解解析器
this.annotationParsers.add(new SpringTransactionAnnotationParser());
this.annotationParsers.add(new JtaTransactionAnnotationParser());
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
/***
true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
public AnnotationTransactionAttributeSource() {
this(true);
}
*/
return new AnnotationTransactionAttributeSource();
}
/***
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add
(new Ejb3TransactionAnnotationParser());
}
}else {
this.annotationParsers
= Collections.singleton
(new SpringTransactionAnnotationParser());
}
}
***/
/**
被@Transactional标记的事务方法的拦截器,实际是一个MethodInterceptor
保存了事务属性信息,事务管理器
在目标方法执行的时候;执行拦截器链
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
//执行代理类的invoke方法的时候会用上
//会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解是否存在
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
//设置事务管理器
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
ProxyTransactionManagementConfiguration是一个配置类。
主要有三个方法,每个方法作用如下:
注入BeanFactoryTransactionAttributeSourceAdvisor
向IOC容器中导入事务增强器:BeanFactoryTransactionAttributeSourceAdvisor
在bean被代理做事务增强时。这个advisor会被选为候选advisor用于增强事务。注意是候选。
BeanFactoryTransactionAttributeSourceAdvisor相当于是1个中介。
把TransactionAttributeSource和TransactionInterceptor 关联起来。
TransactionAttributeSource主要用于获取解析器解析@Transaction注解
TransactionInterceptor主要用于方法拦截执行拦截器链。
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
//注意pointcut是 TransactionAttributeSourcePointcut 间接继承了MethodMatcher
//在判断是否是可用的advisor时会用到这个TransactionAttributeSourcePointcut
//主要是调用matches方法
//TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut
//StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut
//StaticMethodMatcher implements MethodMatcher
//会创建1个methodMatcher
//根据methodMatcher判断方法是否需要匹配被应用事务
private final TransactionAttributeSourcePointcut pointcut
= new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
public void setTransactionAttributeSource
(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
public void setClassFilter(ClassFilter classFilter) {
this.pointcut.setClassFilter(classFilter);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
根据methodMatcher判断方法是否需要匹配被应用事务
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches(Method method, Class<?> targetClass) {
if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return
(tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();
}
注入AnnotationTransactionAttributeSource
向IOC容器中导入事务注解@Transactional的解析器AnnotationTransactionAttributeSource
主要是注入了2个@Transactional的解析器,解析@Transactional的属性值。
this.annotationParsers.add(new SpringTransactionAnnotationParser()); this.annotationParsers.add(new JtaTransactionAnnotationParser());
这2个解析器在2个地方会被用到:
1.判断候选advisor(候选的advisor指的是所有的advisor),是否可以被应用需要调用canApply方法判断
2.在使用jdk代理时,调用代理的invoke方法,会使用这2个解析器去解析@Transactional。然后再去匹配是否需要应用BeanFactoryTransactionAttributeSourceAdvisor。
/***
使用@Bean注入 AnnotationTransactionAttributeSource
主要注入2个@Transactional注解解析器
this.annotationParsers.add(new SpringTransactionAnnotationParser());
this.annotationParsers.add(new JtaTransactionAnnotationParser());
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
/***
true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
public AnnotationTransactionAttributeSource() {
this(true);
}
*/
return new AnnotationTransactionAttributeSource();
}
public AnnotationTransactionAttributeSource() {
this(true);
}
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
注入TransactionInterceptor
BeanFactoryTransactionAttributeSourceAdvisor方法中设置了 advisor.setAdvice(transactionInterceptor());
BeanFactoryTransactionAttributeSourceAdvisor被加入拦截器链,底层使用的还是TransactionInterceptor。
TransactionInterceptor中设置了事务管理器TransactionManager
TransactionManager中实现了方法开启事务 提交事务 异常回滚事务等。
/**
被@Transactional标记的事务方法的拦截器,实际是一个MethodInterceptor
保存了事务属性信息,事务管理器
在目标方法执行的时候;执行拦截器链
*/
//transactionInterceptor()返回1个transactionInterceptor
//有2个用处:
//1.获取调用链时调用getInterceptorsAndDynamicInterceptionAdvice方法
//将BeanFactoryTransactionAttributeSourceAdvisor
//转换为transactionInterceptor
//因为在BeanFactoryTransactionAttributeSourceAdvisor的注入方法中已经设置了
//advisor.setAdvice(transactionInterceptor());
//2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器
//具体看transactionInteceptor的invoke方法
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
//执行代理类的invoke方法的时候会用上
//会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解是否存在
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
//设置事务管理器
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
向IOC容器中导入事务方法拦截器TransactionInterceptor
在使用jdk代理时,调用代理的invoke方法,会取出TransactionInterceptor的TransactionManager做事务增强
@Override
@Nullable
public Object invoke(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, invocation::proceed);
}
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//获取设置的事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
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;
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);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
Object result;
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
}