概覽
事物執(zhí)行流程
類與類的交互
TransactionInterceptor
: 事物代理入口
TransactionAttributeSource
:事物方法掃描都毒、注解信息解析
TransactionManager
:持有連接信息,負(fù)責(zé)事物開啟碰缔、回滾账劲、savepoint等
初始化
TransactionAutoConfiguration
: 引入TransactionManagementConfigurationSelector
以及代理模式
TransactionManagementConfigurationSelector
:引入ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
:生成BeanFactoryTransactionAttributeSourceAdvisor
、TransactionInterceptor
金抡、TransactionAttributeSource
到容器中
BeanFactoryTransactionAttributeSourceAdvisor
:持有TransactionInterceptor
瀑焦、TransactionAttributeSource
。作為Advisor
用于生成代理對(duì)象
AnnotationAwareAspectJAutoProxyCreator
根據(jù)Advisor
定義的切面信息對(duì)目標(biāo)bean
進(jìn)行代理
DataSourceTransactionManagerAutoConfiguration
: 生成TransactionManager
源碼分析
1. 注冊(cè)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)
//默認(rèn)采用代理的方式梗肝,這種方式模式下榛瓮,被代理類內(nèi)部的本地調(diào)用不會(huì)走代理,意味著Spring事物管理不會(huì)介入
@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
引入兩個(gè)類到Spring
容器:AutoProxyRegistrar
跟ProxyTransactionManagementConfiguration
AutoProxyRegistrar
負(fù)責(zé)生成代理對(duì)象的PostProcessor
的注冊(cè)巫击,這個(gè)跟之前Spring AOP
里的AnnotationAwareAspectJAutoProxyCreator
都繼承自AbstractAutoProxyCreator
禀晓,如果Spring
已經(jīng)注冊(cè)了AnnotationAwareAspectJAutoProxyCreator
,則會(huì)避免后續(xù)AbstractAutoProxyCreator
的子類的注冊(cè)
ProxyTransactionManagementConfiguration
負(fù)責(zé)生成攔截器
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
注冊(cè)用于事物管理的BeanFactoryTransactionAttributeSourceAdvisor
到Spring
容器中坝锰,生成代理對(duì)象時(shí)注入該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設(shè)置事物攔截器黔酥,transactionInterceptor負(fù)責(zé)事物方法的自動(dòng)事物管理
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
//主要負(fù)責(zé)事物注解里的屬性解析锭弊,比如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. 生成代理對(duì)象
2.1 注冊(cè)Creator
AutoProxyRegistrar
注冊(cè)InfrastructureAdvisorAutoProxyCreator
到容器中
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (mode == AdviceMode.PROXY) {
//注冊(cè)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
負(fù)責(zé)生成代理對(duì)象
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
有一點(diǎn)小區(qū)別闪唆,因?yàn)槭挛飳?duì)應(yīng)的Advisor
時(shí)已經(jīng)被注冊(cè)到Spring
容器里的涡贱,所以是直接從Spring
中獲取。
public class BeanFactoryAdvisorRetrievalHelper {
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
//從容器中獲取實(shí)現(xiàn)了Advisor的Bean的Name
//Spring 事物攔截器對(duì)應(yīng)的name來自于下面這個(gè)常量
//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) {
//根據(jù)beanName獲取Bean
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
return advisors;
}
初始化BeanFactoryTransactionAttributeSourceAdvisor
時(shí)會(huì)默認(rèn)初始化一個(gè)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
會(huì)根據(jù)目標(biāo)類里是否有Transactional
注解來決定是否生成代理對(duì)象
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
負(fù)責(zé)自動(dòng)事物管理
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = getTransactionAttributeSource();
//通過判斷method上是否有Transactional注解來決定method是否應(yīng)該納入Spring的自動(dòng)事物管理
//參考:SpringTransactionAnnotationParser#parseTransactionAnnotation
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//獲取TransactionManager愕把,默認(rèn)從Spring容器中通過類型TransactionManager獲取
//如果method上的Transactional注解里指定了qualifier拣凹,則根據(jù)qualifier獲取tm
final TransactionManager tm = determineTransactionManager(txAttr);
//響應(yīng)式事物管理
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
//....
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 開啟事物,即設(shè)置autoCommit為false恨豁,mysql數(shù)據(jù)庫即執(zhí)行sql: SET autocommit=0嚣镜,psql會(huì)執(zhí)行Begin
// 處理事物的傳播性以及隔離級(jí)別
// 事物開啟參考:DataSourceTransactionManager#doBegin
// psql參考:PgStatement#executeInternal。QueryExecutorImpl#sendQueryPreamble橘蜜。QueryExecutorImpl#beginTransactionQuery
// mysql參考: ConnectionImpl#setAutoCommit
// psql隔離級(jí)別參考:PgConnection#setTransactionIsolation
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
//如果還有攔截器的話菊匿,將請(qǐng)求傳給下一個(gè)攔截器付呕。否則調(diào)用目標(biāo)方法
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 {
//拿到事物傳播行為跟隔離級(jí)別
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
//生成新的事物對(duì)象
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
//當(dāng)前方法是否已經(jīng)處于事物中,通過transaction是否已持有數(shù)據(jù)庫連接來判斷
if (isExistingTransaction(transaction)) {
// 檢查傳播行為
return handleExistingTransaction(def, transaction, debugEnabled);
}
// 如果當(dāng)前方法不在事物中,同時(shí)傳播行為又是PROPAGATION_MANDATORY
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
// 如果當(dāng)前方法不在事物中跌捆,則在這些傳播行為下開啟一個(gè)新的事物
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//開啟一個(gè)新事物徽职,把連接信息保存到transaction里
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
else {
// 到達(dá)這里當(dāng)前方法不在已存在的事物中并且沒有為當(dāng)前方法創(chuàng)建新的事物
// 能走到這里的傳播級(jí)別只有PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED佩厚、PROPAGATION_SUPPORTS
...
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
}
當(dāng)前方法的調(diào)用者已處于事物中
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
//當(dāng)前方法在事物中但傳播行為是PROPAGATION_NEVER姆钉,則拋出異常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//當(dāng)前方法在事物中但傳播行為是PROPAGATION_NOT_SUPPORTED
//掛起當(dāng)前事物,讓當(dāng)前方法在一個(gè)非事物的環(huán)境下運(yùn)行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
//掛起當(dāng)前事物抄瓦,主要目的是將上一個(gè)事物的連接信息從transaction對(duì)象里清空
//以便在一個(gè)新的連接上以非事物的方式運(yùn)行
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
//掛起當(dāng)前事物并開啟一個(gè)新事物
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
//掛起當(dāng)前事物潮瓶,主要目的是將上一個(gè)事物的連接信息從transaction對(duì)象里清空
//以便在一個(gè)新的連接上開啟一個(gè)新的事物
//startTransaction在發(fā)現(xiàn)transaction#connectionHolder為空時(shí)會(huì)去連接池獲取一個(gè)新的空閑連接
SuspendedResourcesHolder suspendedResources = suspend(transaction);
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
//在當(dāng)前事物下創(chuàng)建一個(gè)savepoint,如果執(zhí)行失敗钙姊,則回滾到savepoing
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
//非JTA事物管理下會(huì)使用savepoint來實(shí)現(xiàn)嵌套事物
if (useSavepointForNestedTransaction()) {
//創(chuàng)建新的事物狀態(tài)信息毯辅,把當(dāng)前事物的
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
//創(chuàng)建savepoint。執(zhí)行sql: SAVEPOINT `xx`
//ConnectionImpl#setSavepoint
status.createAndHoldSavepoint();
return status;
}
else {
//JTA下開啟新事物煞额。通過嵌套的begin commit
return startTransaction(definition, transaction, debugEnabled, null);
}
}
//PROPAGATION_SUPPORTS 跟 PROPAGATION_REQUIRED. 直接在當(dāng)前事物下運(yùn)行
}