相关阅读
- Spring Boot源码简析 事务管理
- Spring Boot源码简析 @EnableAspectJAutoProxy
- Spring Boot源码简析 @EnableAsync
- Spring Boot源码简析 @EnableCaching
TransactionAutoConfiguration
Spring框架提供@Transactional
注解来支持注解驱动的事务管理;
Spring Boot框架默认开启注解驱动的事务管理,即通过TransactionAutoConfiguration
实现事务管理自动配置,代码如下:
@Configuration
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public TransactionManagerCustomizers platformTransactionManagerCustomizers(
ObjectProvider<List<PlatformTransactionManagerCustomizer<?>>> customizers) {
return new TransactionManagerCustomizers(customizers.getIfAvailable());
}
@Configuration
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
public static class TransactionTemplateConfiguration {
private final PlatformTransactionManager transactionManager;
public TransactionTemplateConfiguration(
PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
@Bean
@ConditionalOnMissingBean
public TransactionTemplate transactionTemplate() {
return new TransactionTemplate(this.transactionManager);
}
}
@Configuration
@ConditionalOnBean(PlatformTransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {
@Configuration
@EnableTransactionManagement(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
// 当spring.aop.proxy-target-class属性值为true或者不存在时生效
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
}
根据TransactionAutoConfiguration
的配置信息可知,当引入PlatformTransactionManager
(spring-tx提供)时,该配置类自动生效;
DataSourceTransactionManagerAutoConfiguration
会创建TransactionManager
,如果当前已存在AbstractTransactionManagementConfiguration
,即ProxyTransactionManagementConfiguration
,那么意味着已经引入@EnableTransactionManagement
注解(ProxyTransactionManagementConfiguration
只会被@EnableTransactionManagement
注解引入),因此EnableTransactionManagementConfiguration
不需要生效;否则就会生效,从而引入@EnableTransactionManagement
注解;
EnableTransactionManagementConfiguration
生效的情况下,除非指定spring.aop.proxy-target-class
配置项为false,此时JdkDynamicAutoProxyConfiguration
会生效,否则CglibAutoProxyConfiguration
生效,这两配置都会引入@EnableTransactionManagement
注解,只是注解的proxyTargetClass
属性值不同,该注解会开启事务管理,其实就是引入ProxyTransactionManagementConfiguration
;
@EnableTransactionManagement
源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
// 代理模式:CGLIB or JDK Interface
// 默认为false,表示基于JDK Interface
// 设置为true,会影响所有需要代理的Spring管理的Bean
boolean proxyTargetClass() default false;
// 代理应用模式:Proxy or AspectJ
// Proxy模式只允许通过代理拦截调用,不会拦截同一类中的本地调用
// AspectJ模式下,proxyTargetClass()无效,会拦截同一类中的本地调用
AdviceMode mode() default AdviceMode.PROXY;
// 特定连接点应用多个建议时,事务操作的执行顺序
int order() default Ordered.LOWEST_PRECEDENCE;
}
简析
通过Import机制,引入TransactionManagementConfigurationSelector
;
@Import(TransactionManagementConfigurationSelector.class)
TransactionManagementConfigurationSelector
继承自AdviceModeImportSelector
,AdviceModeImportSelector
实现支持AdviceMode
算法模板,且支持通用的@EnableXxx
注解模式,代码如下:
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 获取本类支持的注解类型
// 对于TransactionManagementConfigurationSelector来说为EnableTransactionManagement
Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
// 获取注解属性数据
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (attributes == null) {
throw new IllegalArgumentException(String.format(
"@%s is not present on importing class '%s' as expected",
annType.getSimpleName(), importingClassMetadata.getClassName()));
}
// 获取注解的AdviceMode属性值
AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName());
// 根据AdviceMode获取引入配置类信息
// 该方法由子类实现算法细节
String[] imports = selectImports(adviceMode);
if (imports == null) {
throw new IllegalArgumentException(String.format("Unknown AdviceMode: '%s'", adviceMode));
}
return imports;
}
@Nullable
protected abstract String[] selectImports(AdviceMode adviceMode);
TransactionManagementConfigurationSelector
实现了算法细节selectImports
,代码如下:
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
根据@EnableTransactionManagement(proxyTargetClass = true)
配置会引入AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
;
AutoProxyRegistrar
AutoProxyRegistrar
实现了ImportBeanDefinitionRegistrar
,用于向容器里注册自动代理创建器AutoProxyCreator
,代码如下:
/**
* importingClassMetadata : 通过Import引入该类的配置类的元数据信息,本例中配置类为CglibAutoProxyConfiguration
* registry : Bean定义容器
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
// 获取配置类的注解列表
// 本例中注解有:
// @Configuration
// @EnableTransactionManagement
// @ConditionalOnProperty
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
// 遍历注解列表
for (String annoType : annoTypes) {
// 获取注解的属性数据
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
if (candidate == null) {
continue;
}
// 获取mode属性值
Object mode = candidate.get("mode");
// 获取proxyTargetClass属性值
Object proxyTargetClass = candidate.get("proxyTargetClass");
// 过滤出@EnableTransactionManagement注解
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
// 本例中,mode为AdviceMode.PROXY,proxyTargetClass为true
if (mode == AdviceMode.PROXY) {
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
// 使用subclass-based proxy
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
if (!candidateFound && logger.isWarnEnabled()) {
// 异常LOG记录
String name = getClass().getSimpleName();
logger.warn(String.format("%s was imported but no annotations were found " +
"having both 'mode' and 'proxyTargetClass' attributes of type " +
"AdviceMode and boolean respectively. This means that auto proxy " +
"creator registration and configuration may not have occurred as " +
"intended, and components may not be proxied as expected. Check to " +
"ensure that %s has been @Import'ed on the same class where these " +
"annotations are declared; otherwise remove the import of %s " +
"altogether.", name, name, name));
}
}
核心逻辑为AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
和AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
,代码如下:
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
@Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断当前容器中是否存在自动代理创建器的Bean定义
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
// 获取已存在的Bean定义
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
// 判断已存在的Bean定义的className和当前是否一致
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
// 不一致则使用优先级更高的
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 根据当前class创建Bean定义并放入容器中
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
// 添加Bean定义的proxyTargetClass属性
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
是一个配置类,继承自AbstractTransactionManagementConfiguration
;
AbstractTransactionManagementConfiguration
实现了ImportAware
接口,会注入@EnableTransactionManagement
注解属性数据,同时注入TransactionManagementConfigurer
配置,代码如下:
public void setImportMetadata(AnnotationMetadata importMetadata) {
// 获取@EnableTransactionManagement注解属性数据
this.enableTx = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
if (this.enableTx == null) {
throw new IllegalArgumentException(
"@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
}
}
@Autowired(required = false)
void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
// // TransactionManagementConfigurer bean只能存在一个
if (configurers.size() > 1) {
throw new IllegalStateException("Only one TransactionManagementConfigurer may exist");
}
TransactionManagementConfigurer configurer = configurers.iterator().next();
// 使用自定义的事务管理器
this.txManager = configurer.annotationDrivenTransactionManager();
}
@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionalEventListenerFactory transactionalEventListenerFactory() {
// 注入监听器工厂,支持@TransactionalEventListener注解标注的方法,来监听事务相关的事件
return new TransactionalEventListenerFactory();
}
ProxyTransactionManagementConfiguration
会向容器中注入BeanFactoryTransactionAttributeSourceAdvisor
、TransactionAttributeSource
、TransactionInterceptor
,代码如下:
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
// 事务管理核心Advisor
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
// 设置增强
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
// 基于注解的事务属性源
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
// 事务拦截器
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
// 设置事务管理器
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
AnnotationTransactionAttributeSource
AnnotationTransactionAttributeSource
是基于注解的事务属性源,内部维护TransactionAnnotationParser
集合,用于解析类或方法的事务属性,代码如下:
public AnnotationTransactionAttributeSource() {
// 默认只能解析public方法
this(true);
}
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet<>(2);
// 默认持有SpringTransactionAnnotationParser支持Spring事务注解
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
// 持有JtaTransactionAnnotationParser支持JTS事务注解
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
// 持有Ejb3TransactionAnnotationParser支持EJB3事务注解
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
// 遍历内部的事务注解解析器
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
// 解析事务属性
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
if (attr != null) {
// 解析成功直接返回
return attr;
}
}
return null;
}
SpringTransactionAnnotationParser
SpringTransactionAnnotationParser
实现了TransactionAnnotationParser
接口,负责解析@Transactional
注解,核心代码如下:
public boolean isCandidateClass(Class<?> targetClass) {
// 指定类是否可能标注@Transactional注解
return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
// 寻找该元素(方法或者类)上是否标注@Transactional注解
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
// 存在,则继续解析@Transactional注解属性
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
}
/**
* 进一步解析@Transactional注解属性
*/
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());
String timeoutString = attributes.getString("timeoutString");
Assert.isTrue(!StringUtils.hasText(timeoutString) || rbta.getTimeout() < 0,
"Specify 'timeout' or 'timeoutString', not both");
rbta.setTimeoutString(timeoutString);
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
rbta.setLabels(Arrays.asList(attributes.getStringArray("label")));
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
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;
}
TransactionInterceptor
TransactionInterceptor
继承自TransactionAspectSupport
,并实现了MethodInterceptor
,代码如下:
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
@Override
@Nullable
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
@Override
public Object getTarget() {
return invocation.getThis();
}
@Override
public Object[] getArguments() {
return invocation.getArguments();
}
});
}
事务管理的核心处理逻辑在父类TransactionAspectSupport
,代码如下:
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// 获取当前事务属性源
TransactionAttributeSource tas = getTransactionAttributeSource();
// 获取当前方法的事物属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 获取事务管理器
final TransactionManager tm = determineTransactionManager(txAttr);
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
boolean hasSuspendingFlowReturnType = isSuspendingFunction &&
COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName());
if (isSuspendingFunction && !(invocation instanceof CoroutinesInvocationCallback)) {
throw new IllegalStateException("Coroutines invocation not supported: " + method);
}
CoroutinesInvocationCallback corInv = (isSuspendingFunction ? (CoroutinesInvocationCallback) invocation : null);
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
Class<?> reactiveType =
(isSuspendingFunction ? (hasSuspendingFlowReturnType ? Flux.class : Mono.class) : method.getReturnType());
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
InvocationCallback callback = invocation;
if (corInv != null) {
callback = () -> CoroutinesUtils.invokeSuspendingFunction(method, corInv.getTarget(), corInv.getArguments());
}
Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, (ReactiveTransactionManager) tm);
if (corInv != null) {
Publisher<?> pr = (Publisher<?>) result;
return (hasSuspendingFlowReturnType ? KotlinDelegate.asFlow(pr) :
KotlinDelegate.awaitSingleOrNull(pr, corInv.getContinuation()));
}
return result;
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 获取方法ID字符串
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 标准的事务管理:getTransaction/commit/rollback calls.
// 创建事务信息,根据事务属性决定是否创建事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 执行原始方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 发生异常,则根据具体异常完成事务(若满足回滚条件才进行回滚)
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清除事务信息
cleanupTransactionInfo(txInfo);
}
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
// 原始方法成功执行完,则可以提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
Object result;
final ThrowableHolder throwableHolder = new ThrowableHolder();
try {
// 交给事务管理器执行
result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
// 准备事务
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
// 执行原始方法
Object retVal = invocation.proceedWithInvocation();
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
// 判断基于当前异常是否回滚
if (txAttr.rollbackOn(ex)) {
// RuntimeException可以触发事务回滚(DefaultTransactionAttribute实现)
// Spring框架认为Checked的异常属于业务的,coder需要处理
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// 无需回滚,但因为发生异常,需要返回null
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;
}
if (throwableHolder.throwable != null) {
// 存在异常则需要抛出
throw throwableHolder.throwable;
}
return result;
}
}
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
if (txInfo.transactionAttribute != null && 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 | Error ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
}
else {
// 不满足事务回滚要求,无需回滚事务
try {
// 提交事务
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
}
}
}
protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
if (txAttr == null || this.beanFactory == null) {
// 直接返回全局事务管理器
return getTransactionManager();
}
// 获取事务属性指定的事务管理器名称
String qualifier = txAttr.getQualifier();
if (StringUtils.hasText(qualifier)) {
// 若指定事务管理器名称,则根据名称查找对应的Bean
return determineQualifiedTransactionManager(this.beanFactory, qualifier);
}
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
// 指定了全局事务管理器名称,则根据名称查找对应的Bean
return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
}
else {
// 获取全局事务管理器
PlatformTransactionManager defaultTransactionManager = getTransactionManager();
if (defaultTransactionManager == null) {
// 从本地缓存中获取默认事务管理器
defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
// 从容器中获取PlatformTransactionManager
defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
// 缓存该事务管理器
this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
private PlatformTransactionManager determineQualifiedTransactionManager(BeanFactory beanFactory, String qualifier) {
// 从本地缓存中获取指定名称的事务管理器
PlatformTransactionManager txManager = this.transactionManagerCache.get(qualifier);
if (txManager == null) {
// 本地缓存不存在,则从容器中根据类型和名称查找事务管理器
txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
beanFactory, PlatformTransactionManager.class, qualifier);
// 缓存该事务管理器,方便下次直接从本地缓存中获取
this.transactionManagerCache.putIfAbsent(qualifier, txManager);
}
return txManager;
}
BeanFactoryTransactionAttributeSourceAdvisor
在ProxyTransactionManagementConfiguration
中,为BeanFactoryTransactionAttributeSourceAdvisor
设置了TransactionInterceptor
作为增强,设置了AnnotationTransactionAttributeSource
作为事务属性源,代码如下:
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
BeanFactoryTransactionAttributeSourceAdvisor
内部的Pointcut
为TransactionAttributeSourcePointcut
,使用AnnotationTransactionAttributeSource
作为事务属性源,实现切入匹配判断,代码如下:
public boolean matches(Method method, @Nullable Class<?> targetClass) {
// 不支持TransactionalProxy
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
// 获取事务属性源
TransactionAttributeSource tas = getTransactionAttributeSource();
// 若当前方法存在事务属性则匹配成功
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
TransactionManagementConfigurer
Spring Boot框架默认会提供DataSourceTransactionManager
、JpaTransactionManager
事务管理器,用户可以通过实现接口TransactionManagementConfigurer
来提供自定义PlatformTransactionManager
实现;
源码
public interface TransactionManagementConfigurer {
PlatformTransactionManager annotationDrivenTransactionManager();
}
配置
@Configuration
public class JdbcConfig implements TransactionManagementConfigurer {
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
}
简析
当自定义TransactionManagementConfigurer
实现并放入容器后,AbstractTransactionManagementConfiguration.setConfigurers
方法会搜索容器内所有的TransactionManagementConfigurer
实现(仅支持一个),并将自定义的事务管理器作为全局默认事务管理器。
@Transactional
源码
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 指定事务管理器名称
@AliasFor("transactionManager")
String value() default "";
// 指定事务管理器名称
@AliasFor("value")
String transactionManager() default "";
// 事务传播行为
Propagation propagation() default Propagation.REQUIRED;
// 事务隔离级别
Isolation isolation() default Isolation.DEFAULT;
// 事务超时时间
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
// 是否只读
boolean readOnly() default false;
// 回滚异常类型
Class<? extends Throwable>[] rollbackFor() default {};
// 回滚异常类名
String[] rollbackForClassName() default {};
// 不回滚异常类型
Class<? extends Throwable>[] noRollbackFor() default {};
// 不回滚异常类名
String[] noRollbackForClassName() default {};
}
使用
- 标注在类上,表示该类的所有方法都被标注;
- 标注在方法上,优先于方法所在类上的注解,若存在的话;
和@EnableAsync区别
- @
EnableTransactionManagement
借助自动代理创建器AutoProxyCreator
实现代理; - @
EnableAsync
借助Bean后置处理器BeanPostProcessor
实现代理;
事务不生效原因
- 事务切入的方法默认必须是public方法,见
AnnotationTransactionAttributeSource
; - Spring框架只对RuntimeException进行回滚;
- 业务和事务在同一个线程中;
- 非事务方法调用同类中的事务方法,则事务不生效;
- 事务方法调用同类中的事务/非事务方法,调用方法的事务生效;
- 非事务方法通过本类的代理对象调用事务方法,被调用方法的事务生效;