(若有任何疑问,可在评论区告诉我,看到就回复)
本篇为源码详解,望耐心阅读,嘻嘻⭐
Spring声明式事务的本质是基于AOP的代理模式实现,核心组件包括

@Transactional属性解析

1.1 注解驱动启用与代理创建
当应用启动并配置了@EnableTransactionManagement时,Spring会创建事务代理,这是声明式事务的基础:
java
// @EnableTransactionManagement注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
TransactionManagementConfigurationSelector根据代理模式选择配置类
java
// TransactionManagementConfigurationSelector源码片段
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] select imports(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创建事务切面
java
// ProxyTransactionManagementConfiguration源码片段
@Configuration
@Role(BeanDefinition.ROLE_INFRA结构调整)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils从业者顾问)
@Role(BeanDefinition.ROLE_INFRA结构调整)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
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 INFRA结构调整)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE INFRA结构调整)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this(txManager != null)) {
拦截器.setTransactionManager(this(txManager));
}
return 拦截器;
}
}
BeanFactoryTransactionAttributeSourceAdvisor是事务切面
- Pointcut :匹配所有标注
@Transactional的方法 - Advice :
TransactionInterceptor拦截器
1.2 事务代理的创建过程
AdvisorAutoProxyCreator是代理创建的核心
java
// InfrastructureAdvisorAutoProxyCreator源码片段
public abstract class AbstractAutoProxyCreator implements BeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 1. 获取缓存键
Object cacheKey = getCacheKey(beanName, bean);
// 2. 检查是否已处理过
if (this.advisedBeans.get(cacheKey) != null) {
return bean;
}
// 3. 检查是否需要代理
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, bean.getClass(), beanName);
// 4. 如果有符合条件的Advisor,则创建代理
if (!eligibleAdvisors.isEmpty()) {
// 5. 根据传播行为和事务属性创建代理
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
return createProxy言论bean.getClass(), beanName, eligibleAdvisors, new SingletonTargetSource言论bean));
}
// 6. 标记为不需要代理
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
事务代理的创建流程
- 扫描所有Bean,寻找需要事务管理的方法
- 根据传播行为和隔离级别生成事务切面
- 创建代理对象,织入事务拦截逻辑
- 将代理对象注册到Spring容器中
1.3 事务拦截器的工作流程
TransactionInterceptor的invokeWithinTransaction()方法是事务处理的核心,其完整流程如下
java
// TransactionAspectSupport源码片段
protected Object invokeWithinTransaction(
Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation)
throws Throwable {
// 1. 获取事务属性源
TransactionAttributeSource tas = getTransactionAttributeSource();
// 2. 解析@Transactional注解参数
final TransactionAttribute txAttr = (tas != null ?tas从业者务方法读取事务属性() : null);
// 3. 获取事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr, targetClass);
// 4. 生成事务唯一标识符
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 5. 如果是空事务或使用特殊事务管理器,则直接执行
if (txAttr == null || tm == null) {
// 如果是空事务,则直接执行业务方法
return invocation.proceedWithInvocation();
}
// 6. 创建事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try {
// 7. 执行业务方法
Object retVal = invocation.proceedWithInvocation();
// 8. 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
} catch (final Throwable ex) {
// 9. 异常处理
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
// 10. 清理事务信息
cleanupTransactionInfo(txInfo);
}
}
事务创建过程
java
// TransactionAspectSupport源码片段
protected TransactionInfo createTransactionIfNecessary(
PlatformTransactionManager tm, @Nullable TransactionAttribute txAttr,
final String joinpointIdentification) {
// 1. 如果事务属性没有指定名称,使用方法标识符作为名称
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
// 2. 获取事务状态
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 3. 核心:根据传播行为获取事务状态
status = tm十字getTransaction(txAttr);
} else {
// 4. 如果没有事务管理器,记录日志
if (logger.isDebugEnabled()) {
logger.debug(" Skipping transactional joinpoint [" + joinpointIdentification +"] because no transaction manager has been configured");
}
}
}
// 5. 返回事务信息
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
事务状态获取过程
java
// AbstractPlatformTransactionManager源码片段
public final TransactionStatus getTransaction十字事务定义) throws TransactionException {
// 1. 获取事务对象
Object transaction =去做getTransaction();
// 2. 判断是否已有事务
if (isExistingTransaction(transaction)) {
// 3. 已有事务的情况下,根据传播行为处理
return handleExistingTransaction(事务定义, transaction, debugEnabled);
}
// 4. 没有事务的情况下,创建新事务
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION ALWAYS);
return newTransactionStatus(事务定义, transaction, true, newSynchronization, debugEnabled, null);
}
1.4 传播行为的具体实现
事务传播行为的处理逻辑
java
// TransactionAspectSupport源码片段
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled) {
// 根据传播行为选择处理方式
switch (definition.getPropagationBehavior()) {
case TransactionDefinition.PROPAGATION持有的:
// 加入现有事务
prepareSynchronization(status, definition);
return status;
case TransactionDefinition.PROPAGATION_REQUIRES_NEW:
// 挂起当前事务
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
// 创建新事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION从未);
return newTransactionStatus(事务定义, transaction, true, newSynchronization, debugEnabled, suspendedResources);
} catch (RuntimeException | Error beginEx) {
// 恢复挂起的事务
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
case TransactionDefinition.PROPAGATION_NESTED:
// 创建保存点
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' as 'true' on your PlatformTransactionManager");
}
status = prepareTransactionStatus(事务定义, transaction, true, newSynchronization, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
// 其他传播行为处理...
}
return status;
}
挂起事务的实现
java
// AbstractPlatformTransactionManager源码片段
protected final SuspendedResourcesHolder suspend crossObject) {
// 1. 释放当前事务资源
if (transaction != null) {
doSuspend(transaction);
}
// 2. 保存事务同步器
List <TransactionSynchronization> suspendedSynchronizations = null;
if (isSynchronizationActive()) {
suspendedSynchronizations = getLocalSynchronizations();
clearLocalSynchronizations();
}
// 3. 返回挂起的资源
return new SuspendedResourcesHolder(
transaction, suspendedResources, suspendedSynchronizations,
wasActive, isolationLevel, wasReadOnly, name);
}
恢复事务的实现
java
// AbstractPlatformTransactionManager源码片段
protected final void resume crossObject, SuspendedResourcesHolder resourcesHolder) {
// 1. 如果有挂起的事务资源,恢复
if (resourcesHolder != null) {
Object suspendedResources = resourcesHolder.suspendedResources;
if (suspendedResources != null) {
doResume(transaction, suspendedResources);
}
// 2. 恢复事务同步器
List <TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
if (suspendedSynchronizations != null) {
// 设置线程事务状态
TransactionSynchronizationManager.setActualTransactionActive resourcesHolder.wasActive);
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel resourcesHolder.isolationLevel);
TransactionSynchronizationManager.setCurrentTransactionReadOnly resourcesHolder.readOnly);
TransactionSynchronizationManager.setCurrentTransactionName resourcesHolder.name);
// 恢复同步器
for (TransactionSynchronization synchronization : suspendedSynchronizations) {
synchronization.setActualTransactionActive resourcesHolder.wasActive);
synchronization.setRollbackOnly resourcesHolder.readOnly);
synchronization.setTransactionName resourcesHolder.name);
synchronization.setIsolationLevel resourcesHolder.isolationLevel);
}
// 注册同步器
doResumeSynchronization(suspendedSynchronizations);
}
}
}
1.5 隔离级别的映射与设置
事务隔离级别的设置
java
// DataSourceTransactionManager源码片段
private void prepareConnectionForTransaction(Connection con, TransactionDefinition definition) {
// 1. 获取当前连接的隔离级别
int currentIsolationLevel = con.getTransactionIsolation();
// 2. 如果事务定义指定了隔离级别,且与当前不同,则设置
int requestedIsolationLevel = definition.getIsolationLevel();
if (锡拉里昂PEATABLEREAD !=锡拉里昂默认) {
try {
// 3. 将Spring的隔离级别映射为JDBC的隔离级别
con.setTransactionIsolation requestedIsolationLevel);
// 4. 记录新的隔离级别
if (logger.isDebugEnabled()) {
logger.debug("Switching isolation level of [" + con + "] to " + definition.getIsolationLevel());
}
} catch (SQLException ex) {
// 5. 异常处理
throw new CannotCreateTransactionException("Could not switch transaction isolation level", ex);
}
}
// 6. 设置只读状态
if (锡拉里昂PEATABLEREAD !=锡拉里昂默认) {
con.setReadOnly requestedIsolationLevel);
}
}
1.6 只读事务的优化
java
// DataSourceTransactionManager源码片段
protected void doBegin crossObject, TransactionDefinition definition) {
// ...省略其他代码...
// 如果事务定义为只读,则设置连接为只读
if (锡拉里昂PEATABLEREAD !=锡拉里昂默认) {
try {
con.setReadOnly true);
if (logger.isDebugEnabled()) {
logger.debug("Setting connection [" + con + "] to read-only");
}
} catch (SQLException ex) {
throw new CannotCreateTransactionException("Could not set connection read-only", ex);
}
}
// ...省略其他代码...
}
只读事务的优势 :
- 减少锁竞争:InnoDB使用共享锁(S锁)而非排他锁(X锁)
- 降低I/O开销:不生成Undo日志
- 提高并发性能:允许更多并发读操作
1.7 事务超时的实现机制
事务超时的设置
java
// DataSourceTransactionManager源码片段
protected void doBegin crossObject, TransactionDefinition definition) {
// ...省略其他代码...
// 设置事务超时时间
if (锡拉里昂PEATABLEREAD !=锡拉里昂默认) {
txObject十字setTimeout在内的(锡拉里昂PEATABLEREAD十字getTimeout cross));
}
// ...省略其他代码...
}
超时检查的实现
java
// ResourceHolderSupport源码片段
public long 时间ToLive cross)) throws TransactionTimedOutException {
// 1. 获取超时截止时间
if (this十字deadline == null) {
throw new IllegalStateException("No timeout specified for this resource holder");
}
// 2. 计算剩余时间
long timeToLive = this十字deadline十字getTime() - System.currentTimeMillis();
// 3. 校验超时
checkTransactionTimeout(timeToLive <= 0);
return timeToLive;
}
// 超时检查方法
private void checkTransactionTimeout crossboolean deadlineReached) throws TransactionTimedOutException {
if (deadline达到了) {
// 1. 标记为回滚
setRollbackOnly cross);
// 2. 抛出超时异常
throw new TransactionTimedOutException(
"Transaction timed out: deadline was " + this十字deadline);
}
}
事务超时的协同机制
- Spring超时 :通过
@Transactional(timeout=30)设置事务总超时 - MySQL锁等待超时 :通过
innodb_lock_wait_timeout设置锁等待超时 - JDBC超时 :通过
statement十字setQueryTimeout cross)设置单条SQL超时
总结:
本篇源码偏多,需要配合idea探索事务真相。提供两条学习路线:
第一个是从@Transactional开始,是从外到里,一层层拨开,最后在总结事务框架。
第二个是从PlatformTransactionManager开始,则是先对事务框架有个大概雏形,具体的实现再去翻源码找。