概览
事物执行流程
类与类的交互
TransactionInterceptor
: 事物代理入口
TransactionAttributeSource
:事物方法扫描、注解信息解析
TransactionManager
:持有连接信息,负责事物开启、回滚、savepoint等
初始化
TransactionAutoConfiguration
: 引入TransactionManagementConfigurationSelector
以及代理模式
TransactionManagementConfigurationSelector
:引入ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
:生成BeanFactoryTransactionAttributeSourceAdvisor
、TransactionInterceptor
、TransactionAttributeSource
到容器中
BeanFactoryTransactionAttributeSourceAdvisor
:持有TransactionInterceptor
、TransactionAttributeSource
。作为Advisor
用于生成代理对象
AnnotationAwareAspectJAutoProxyCreator
根据Advisor
定义的切面信息对目标bean
进行代理
DataSourceTransactionManagerAutoConfiguration
: 生成TransactionManager
源码分析
1. 注册Advisor
TransactionAutoConfiguration
通过Import
引入TransactionManagementConfigurationSelector
@AutoConfiguration(after = { JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
@ConditionalOnClass(PlatformTransactionManager.class)
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(TransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {
@Configuration(proxyBeanMethods = false)
//默认采用代理的方式,这种方式模式下,被代理类内部的本地调用不会走代理,意味着Spring事物管理不会介入
@EnableTransactionManagement(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
}
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
}
TransactionManagementConfigurationSelector
引入两个类到Spring
容器:AutoProxyRegistrar
跟ProxyTransactionManagementConfiguration
AutoProxyRegistrar
负责生成代理对象的PostProcessor
的注册,这个跟之前Spring AOP
里的AnnotationAwareAspectJAutoProxyCreator
都继承自AbstractAutoProxyCreator
,如果Spring
已经注册了AnnotationAwareAspectJAutoProxyCreator
,则会避免后续AbstractAutoProxyCreator
的子类的注册
ProxyTransactionManagementConfiguration
负责生成拦截器
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
}
ProxyTransactionManagementConfiguration
注册用于事物管理的BeanFactoryTransactionAttributeSourceAdvisor
到Spring
容器中,生成代理对象时注入该advisor
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
//为advisor设置事物拦截器,transactionInterceptor负责事物方法的自动事物管理
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
//主要负责事物注解里的属性解析,比如Transactional里的rollbackFor
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
2. 生成代理对象
2.1 注册Creator
AutoProxyRegistrar
注册InfrastructureAdvisorAutoProxyCreator
到容器中
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (mode == AdviceMode.PROXY) {
//注册InfrastructureAdvisorAutoProxyCreator
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
}
}
}
public abstract class AopConfigUtils {
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
}
AbstractAutoProxyCreator
的postProcessAfterInitialization
负责生成代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//前面AOP的博文有分析过
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
}
2.2 获取Advisor
这里跟aspect
有一点小区别,因为事物对应的Advisor
时已经被注册到Spring
容器里的,所以是直接从Spring
中获取。
public class BeanFactoryAdvisorRetrievalHelper {
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
//从容器中获取实现了Advisor的Bean的Name
//Spring 事物拦截器对应的name来自于下面这个常量
//TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
//根据beanName获取Bean
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
return advisors;
}
初始化BeanFactoryTransactionAttributeSourceAdvisor
时会默认初始化一个TransactionAttributeSourcePointcut
作为该advisor
的Point
,该Point
指向带Transactional注解的方法
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
//初始化pointcut
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
}
TransactionAttributeSourcePointcut
会根据目标类里是否有Transactional
注解来决定是否生成代理对象
private class TransactionAttributeSourceClassFilter implements ClassFilter {
@Override
public boolean matches(Class<?> clazz) {
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
TransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
//判断类里是否有Transactional注解
return (tas == null || tas.isCandidateClass(clazz));
}
}
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
@Override
public boolean isCandidateClass(Class<?> targetClass) {
return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}
}
3. 事物管理
3.1 入口
TransactionAspectSupport
#invokeWithinTransaction
负责自动事物管理
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = getTransactionAttributeSource();
//通过判断method上是否有Transactional注解来决定method是否应该纳入Spring的自动事物管理
//参考:SpringTransactionAnnotationParser#parseTransactionAnnotation
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//获取TransactionManager,默认从Spring容器中通过类型TransactionManager获取
//如果method上的Transactional注解里指定了qualifier,则根据qualifier获取tm
final TransactionManager tm = determineTransactionManager(txAttr);
//响应式事物管理
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
//....
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 开启事物,即设置autoCommit为false,mysql数据库即执行sql: SET autocommit=0,psql会执行Begin
// 处理事物的传播性以及隔离级别
// 事物开启参考:DataSourceTransactionManager#doBegin
// psql参考:PgStatement#executeInternal。QueryExecutorImpl#sendQueryPreamble。QueryExecutorImpl#beginTransactionQuery
// mysql参考: ConnectionImpl#setAutoCommit
// psql隔离级别参考:PgConnection#setTransactionIsolation
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)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//提交事物
commitTransactionAfterReturning(txInfo);
return retVal;
}
}
3.2 事物传播行为
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
//拿到事物传播行为跟隔离级别
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
//生成新的事物对象
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
//当前方法是否已经处于事物中,通过transaction是否已持有数据库连接来判断
if (isExistingTransaction(transaction)) {
// 检查传播行为
return handleExistingTransaction(def, transaction, debugEnabled);
}
// 如果当前方法不在事物中,同时传播行为又是PROPAGATION_MANDATORY
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
// 如果当前方法不在事物中,则在这些传播行为下开启一个新的事物
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//开启一个新事物,把连接信息保存到transaction里
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
else {
// 到达这里当前方法不在已存在的事物中并且没有为当前方法创建新的事物
// 能走到这里的传播级别只有PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED、PROPAGATION_SUPPORTS
...
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
}
当前方法的调用者已处于事物中
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
//当前方法在事物中但传播行为是PROPAGATION_NEVER,则抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//当前方法在事物中但传播行为是PROPAGATION_NOT_SUPPORTED
//挂起当前事物,让当前方法在一个非事物的环境下运行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
//挂起当前事物,主要目的是将上一个事物的连接信息从transaction对象里清空
//以便在一个新的连接上以非事物的方式运行
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
//挂起当前事物并开启一个新事物
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
//挂起当前事物,主要目的是将上一个事物的连接信息从transaction对象里清空
//以便在一个新的连接上开启一个新的事物
//startTransaction在发现transaction#connectionHolder为空时会去连接池获取一个新的空闲连接
SuspendedResourcesHolder suspendedResources = suspend(transaction);
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
//在当前事物下创建一个savepoint,如果执行失败,则回滚到savepoing
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//非JTA事物管理下会使用savepoint来实现嵌套事物
if (useSavepointForNestedTransaction()) {
//创建新的事物状态信息,把当前事物的
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
//创建savepoint。执行sql: SAVEPOINT `xx`
//ConnectionImpl#setSavepoint
status.createAndHoldSavepoint();
return status;
}
else {
//JTA下开启新事物。通过嵌套的begin commit
return startTransaction(definition, transaction, debugEnabled, null);
}
}
//PROPAGATION_SUPPORTS 跟 PROPAGATION_REQUIRED. 直接在当前事物下运行
}