事务核心原理 - PlatformTransactionManager 与事务传播行为源码解析
一、Spring 事务抽象概述
Spring Framework 提供了一套声明式事务管理的抽象层,使开发者无需直接与底层事务 API(如 JDBC、JTA、JPA)打交道。其核心设计围绕三个顶级接口展开:TransactionManager、PlatformTransactionManager 和 ReactiveTransactionManager。
Spring 事务抽象的核心目标:
- 统一编程模型:屏蔽不同事务 API 的差异,提供一致的编程体验
- 声明式事务:通过
@Transactional注解或 XML 配置声明事务边界 - 传播行为:定义事务方法之间的调用行为语义
- 与框架深度集成:与 AOP、SpEL、Bean 生命周期无缝配合
二、PlatformTransactionManager 接口体系
2.1 接口层级关系
TransactionManager(标记接口,5.3.x 新增)
├── PlatformTransactionManager(命令式事务)
│ ├── AbstractPlatformTransactionManager(抽象骨架实现)
│ │ ├── DataSourceTransactionManager(JDBC 事务)
│ │ ├── JpaTransactionManager(JPA 事务)
│ │ ├── HibernateTransactionManager(Hibernate 事务)
│ │ ├── JtaTransactionManager(JTA 全局事务)
│ │ └── WebSphereUowTransactionManager(WebSphere 专用)
│ └── ...(其他实现)
└── ReactiveTransactionManager(响应式事务)
└── AbstractReactiveTransactionManager
└── ReactiveTransactionManager 的具体实现2.2 TransactionManager(标记接口)
Spring 5.3.x 引入的顶层标记接口,作为整个事务体系的新根:
package org.springframework.transaction;
/**
* Spring 5.3 引入的标记接口,作为 TransactionManager 的根接口。
* 其主要目的是统一 PlatformTransactionManager 和 ReactiveTransactionManager。
*/
public interface TransactionManager {
}该接口本身不定义任何方法,纯粹作为类型标记存在。在此之前,PlatformTransactionManager 是唯一的顶层接口,引入此标记接口是为了在 5.3 版本中更好地支持响应式事务体系。
2.3 PlatformTransactionManager(命令式事务核心)
这是 Spring 声明式事务的核心接口,定义了事务管理的三个基本操作:
package org.springframework.transaction;
public interface PlatformTransactionManager extends TransactionManager {
/**
* 根据指定的 TransactionDefinition 获取事务状态。
* 返回值 TransactionStatus 代表当前事务的状态,可用于后续的提交或回滚。
*
* @param definition 事务定义信息(隔离级别、传播行为、超时、只读等)
* @return TransactionStatus 事务状态对象
* @throws TransactionException 事务异常
*/
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
/**
* 提交事务。
* 注意:此方法会根据 TransactionStatus 判断是提交还是回滚。
* 如果事务已被标记为 rollback-only,则执行回滚而非提交。
*
* @param status 事务状态对象(由 getTransaction 返回)
* @throws TransactionException 事务异常
*/
void commit(TransactionStatus status) throws TransactionException;
/**
* 回滚事务。
* 注意:此方法执行的是"强制回滚",与 commit 中隐式回滚不同。
*
* @param status 事务状态对象(由 getTransaction 返回)
* @throws TransactionException 事务异常
*/
void rollback(TransactionStatus status) throws TransactionException;
}2.4 ReactiveTransactionManager
Spring 5.3 引入的响应式事务管理接口,与 PlatformTransactionManager 形成对称设计:
package org.springframework.transaction;
import reactor.core.publisher.Mono;
public interface ReactiveTransactionManager extends TransactionManager {
Mono<ReactiveTransaction> getReactiveTransaction(
@Nullable TransactionDefinition definition) throws TransactionException;
Mono<Void> commit(ReactiveTransaction transaction) throws TransactionException;
Mono<Void> rollback(ReactiveTransaction transaction) throws TransactionException;
}三、核心实现类分析
3.1 DataSourceTransactionManager
最常用的实现,管理基于 javax.sql.DataSource 的单数据源 JDBC 事务。其核心是直接操作 java.sql.Connection 的事务 API:
package org.springframework.jdbc.datasource;
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
@Nullable
private DataSource dataSource;
private boolean enforceReadOnly = false;
public DataSourceTransactionManager() {
// 默认允许嵌套事务(基于 Savepoint)
setNestedTransactionAllowed(true);
}
public DataSourceTransactionManager(DataSource dataSource) {
this();
setDataSource(dataSource);
afterPropertiesSet();
}
// ---------- 核心模板方法实现 ----------
@Override
protected Object doGetTransaction() {
// 从 DataSourceUtils 中获取当前线程绑定的 Connection 持有者
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
// 关键:从资源持有器中获取当前线程的 ConnectionHolder
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager
.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
// 如果当前没有 ConnectionHolder,则从 DataSource 获取新连接
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = obtainDataSource().getConnection();
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();
// ---- 设置事务的关键属性 ----
// 设置事务隔离级别
Integer previousIsolationLevel = DataSourceUtils.prepareTransactionForConnection(
con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// 设置只读提示(某些数据库驱动会利用此提示进行优化)
if (definition.isReadOnly()) {
if (this.enforceReadOnly && con instanceof ConnectionProxy) {
try {
// 通过 setReadOnly(true) 通知数据库连接
con.setReadOnly(true);
} catch (SQLException ex) {
// 某些数据库不支持只读模式,这里降级处理
logger.debug("Could not set JDBC Connection as readOnly", ex);
}
}
}
// === 核心:关闭自动提交并手动管理事务 ===
// 如果连接当前是自动提交模式,则关闭它
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
con.setAutoCommit(false);
}
// 将事务标记为活跃
txObject.getConnectionHolder().setTransactionActive(true);
// 绑定到当前线程
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(
obtainDataSource(), txObject.getConnectionHolder());
}
} catch (Throwable ex) {
// 异常回滚:关闭连接
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject =
(DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
con.commit(); // 直接调用 JDBC Connection 的 commit
} catch (SQLException ex) {
throw new TransactionSystemException("Could not commit JDBC transaction", ex);
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject =
(DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
con.rollback(); // 直接调用 JDBC Connection 的 rollback
} catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}
@Override
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject =
(DataSourceTransactionObject) status.getTransaction();
txObject.getConnectionHolder().setRollbackOnly();
}
@Override
protected void doCleanupAfterCompletion(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
// 从当前线程解绑资源
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(obtainDataSource());
}
// 恢复连接的自动提交状态
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (txObject.isMustRestoreAutoCommit()) {
con.setAutoCommit(true);
}
// 恢复隔离级别
DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
} catch (SQLException ex) {
logger.debug("Could not reset JDBC Connection after transaction", ex);
}
// 如果是新获取的连接,则释放
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
}
txObject.getConnectionHolder().clear();
}
// ---------- 内部状态对象 ----------
private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {
private boolean newConnectionHolder;
private boolean mustRestoreAutoCommit;
public void setConnectionHolder(@Nullable ConnectionHolder connectionHolder, boolean newConnectionHolder) {
super.setConnectionHolder(connectionHolder);
this.newConnectionHolder = newConnectionHolder;
}
public boolean isNewConnectionHolder() {
return this.newConnectionHolder;
}
public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {
this.mustRestoreAutoCommit = mustRestoreAutoCommit;
}
public boolean isMustRestoreAutoCommit() {
return this.mustRestoreAutoCommit;
}
}
}关键设计点
- 线程绑定资源:使用
TransactionSynchronizationManager将ConnectionHolder绑定到当前线程(ThreadLocal),确保同一事务中所有 DAO 操作共享同一个 JDBC Connection。 - 自动提交控制:事务开始时调用
con.setAutoCommit(false),结束恢复con.setAutoCommit(true)。 - 延迟获取连接:
doGetTransaction()中尝试从TransactionSynchronizationManager获取已有连接;doBegin()中才真正从 DataSource 获取新连接。
3.2 JpaTransactionManager
管理基于 JPA(Java Persistence API)的 EntityManager 事务。与 DataSourceTransactionManager 不同,它操作的是 JPA 的 EntityTransaction:
package org.springframework.orm.jpa;
public class JpaTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, BeanFactoryAware {
@Nullable
private EntityManagerFactory entityManagerFactory;
// JPA 事务的关键:通过 EntityManager 获取事务
@Override
protected Object doGetTransaction() {
JpaTransactionObject txObject = new JpaTransactionObject();
// 从当前线程获取已绑定的 EntityManagerHolder
EntityManagerHolder holder = (EntityManagerHolder)
TransactionSynchronizationManager.getResource(obtainEntityManagerFactory());
txObject.setEntityManagerHolder(holder, false);
return txObject;
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
JpaTransactionObject txObject = (JpaTransactionObject) transaction;
// 获取或创建 EntityManager
EntityManager em = txObject.getEntityManager();
if (em == null) {
em = obtainEntityManagerFactory().createEntityManager();
txObject.setEntityManagerHolder(new EntityManagerHolder(em), true);
}
// 开启 JPA 事务
if (!em.getTransaction().isActive()) {
em.getTransaction().begin(); // 委托给 JPA EntityTransaction
}
// 设置只读提示——JPA 2.1+ 的查询提示
if (definition.isReadOnly()) {
em.setProperty("javax.persistence.query.timeout",
definition.getTimeout() > 0 ? definition.getTimeout() : 0);
}
// 绑定到线程
if (txObject.isNewEntityManagerHolder()) {
TransactionSynchronizationManager.bindResource(
obtainEntityManagerFactory(), txObject.getEntityManagerHolder());
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) {
JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction();
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager()
.getTransaction();
if (!tx.isActive()) {
throw new TransactionTimedOutException("JPA transaction not active");
}
tx.commit(); // 委托给 JPA EntityTransaction.commit()
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction();
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager()
.getTransaction();
if (tx.isActive()) {
tx.rollback(); // 委托给 JPA EntityTransaction.rollback()
}
}
}与 DataSourceTransactionManager 的核心差异
| 特性 | DataSourceTransactionManager | JpaTransactionManager |
|---|---|---|
| 底层资源 | java.sql.Connection | javax.persistence.EntityManager |
| 事务操作 | con.commit()/rollback() | em.getTransaction().commit()/rollback() |
| 资源持有 | ConnectionHolder | EntityManagerHolder |
| 适用场景 | 原生 JDBC / MyBatis 等 | JPA / Hibernate 实现 |
3.3 HibernateTransactionManager
管理 Hibernate Session 的事务,实际上是 Hibernate 4/5 时代的产物。操作的是 org.hibernate.Transaction:
package org.springframework.orm.hibernate5;
public class HibernateTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {
@Nullable
private SessionFactory sessionFactory;
@Override
protected Object doGetTransaction() {
HibernateTransactionObject txObject = new HibernateTransactionObject();
SessionHolder holder = (SessionHolder)
TransactionSynchronizationManager.getResource(obtainSessionFactory());
txObject.setSessionHolder(holder, false);
return txObject;
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
Session session = null;
try {
if (!txObject.hasSessionHolder() ||
txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Session newSession = obtainSessionFactory().openSession();
txObject.setSessionHolder(new SessionHolder(newSession), true);
}
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
session = txObject.getSessionHolder().getSession();
// 设置 FlushMode
if (definition.isReadOnly()) {
session.setFlushMode(FlushMode.MANUAL);
} else {
session.setFlushMode(FlushMode.AUTO);
}
// === 开启 Hibernate 事务 ===
// Hibernate Session 底层通过 session.beginTransaction() 创建事务
Transaction hibernateTx = session.beginTransaction();
txObject.getSessionHolder().setTransaction(hibernateTx);
// 绑定到线程
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(
obtainSessionFactory(), txObject.getSessionHolder());
}
} catch (Exception ex) {
if (txObject.isNewSessionHolder()) {
SessionUtils.closeSession(session);
txObject.setSessionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
}
}
}四、TransactionDefinition —— 事务定义接口
TransactionDefinition 定义了事务的元数据,包括隔离级别、传播行为、超时时间和只读状态:
package org.springframework.transaction;
public interface TransactionDefinition {
// ==================== 传播行为常量(7种) ====================
/**
* 0 - 支持当前事务,如果不存在则创建新事务。
* 这是最常用的传播行为。
*/
int PROPAGATION_REQUIRED = 0;
/**
* 1 - 支持当前事务,如果不存在则以非事务方式执行。
*/
int PROPAGATION_SUPPORTS = 1;
/**
* 2 - 支持当前事务,如果不存在则抛出异常。
*/
int PROPAGATION_MANDATORY = 2;
/**
* 3 - 创建新事务,如果存在当前事务则挂起。
*/
int PROPAGATION_REQUIRES_NEW = 3;
/**
* 4 - 以非事务方式执行,如果存在当前事务则挂起。
*/
int PROPAGATION_NOT_SUPPORTED = 4;
/**
* 5 - 以非事务方式执行,如果存在当前事务则抛出异常。
*/
int PROPAGATION_NEVER = 5;
/**
* 6 - 如果存在当前事务则在嵌套事务中执行,否则行为同 REQUIRED。
*/
int PROPAGATION_NESTED = 6;
// ==================== 隔离级别常量(5种) ====================
/** -1 - 使用底层数据存储的默认隔离级别 */
int ISOLATION_DEFAULT = -1;
/** 1 - 读未提交 */
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
/** 2 - 读已提交(大多数数据库的默认级别,如 PostgreSQL、Oracle) */
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
/** 4 - 可重复读(MySQL InnoDB 默认级别) */
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
/** 8 - 串行化 */
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
// ==================== 超时和默认值 ====================
/** -1 - 使用底层事务系统的默认超时 */
int TIMEOUT_DEFAULT = -1;
// ==================== 接口方法 ====================
/**
* 返回传播行为,默认为 PROPAGATION_REQUIRED。
*/
default int getPropagationBehavior() {
return PROPAGATION_REQUIRED;
}
/**
* 返回隔离级别,默认为 ISOLATION_DEFAULT。
*/
default int getIsolationLevel() {
return ISOLATION_DEFAULT;
}
/**
* 返回事务超时时间(秒),默认为 -1(无超时)。
*/
default int getTimeout() {
return TIMEOUT_DEFAULT;
}
/**
* 是否只读事务,默认为 false。
*/
default boolean isReadOnly() {
return false;
}
/**
* 返回事务名称(用于监控和日志),5.0 新增。
*/
@Nullable
default String getName() {
return null;
}
// ==================== 静态内部类 ====================
/**
* 默认的 TransactionDefinition 实现(PROPAGATION_REQUIRED + ISOLATION_DEFAULT)。
*/
static TransactionDefinition withDefaults() {
return new DefaultTransactionDefinition();
}
}DefaultTransactionDefinition 实现
package org.springframework.transaction.support;
public class DefaultTransactionDefinition implements TransactionDefinition, Serializable {
private int propagationBehavior = PROPAGATION_REQUIRED;
private int isolationLevel = ISOLATION_DEFAULT;
private int timeout = TIMEOUT_DEFAULT;
private boolean readOnly = false;
@Nullable
private String name;
// 构造函数、getter/setter 省略...
@Override
public final int getPropagationBehavior() {
return this.propagationBehavior;
}
// equals/hashCode 确保相同定义的事务可以复用
}DefaultTransactionDefinition 验证逻辑
public class DefaultTransactionDefinition implements TransactionDefinition {
/**
* 验证传播行为值的合法性
*/
public void setPropagationBehavior(int propagationBehavior) {
if (propagationBehavior != PROPAGATION_REQUIRED &&
propagationBehavior != PROPAGATION_SUPPORTS &&
propagationBehavior != PROPAGATION_MANDATORY &&
propagationBehavior != PROPAGATION_REQUIRES_NEW &&
propagationBehavior != PROPAGATION_NOT_SUPPORTED &&
propagationBehavior != PROPAGATION_NEVER &&
propagationBehavior != PROPAGATION_NESTED) {
throw new IllegalArgumentException("Invalid propagation behavior: " + propagationBehavior);
}
this.propagationBehavior = propagationBehavior;
}
}五、@Transactional 注解解析流程
@Transactional 注解是整个声明式事务的核心入口,它的解析流程涉及多个层次。
5.1 @Transactional 注解定义
package org.springframework.transaction.annotation;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 指定事务管理器 Bean 名称(默认取类型匹配或名为 "transactionManager" 的 Bean)
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
// 传播行为,默认为 REQUIRED
Propagation propagation() default Propagation.REQUIRED;
// 隔离级别,默认为 DEFAULT(使用数据库默认级别)
Isolation isolation() default Isolation.DEFAULT;
// 超时时间(秒),默认为 -1(使用事务系统默认超时)
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
// 是否只读,默认为 false
boolean readOnly() default false;
// 指定哪些异常类型触发回滚(默认对 RuntimeException 和 Error 回滚)
Class<? extends Throwable>[] rollbackFor() default {};
// 指定哪些异常类型不触发回滚
Class<? extends Throwable>[] noRollbackFor() default {};
// 异常名称模式(SpEL 风格)
String[] rollbackForClassName() default {};
String[] noRollbackForClassName() default {};
}5.2 枚举定义
package org.springframework.transaction.annotation;
public enum Propagation {
REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
NEVER(TransactionDefinition.PROPAGATION_NEVER),
NESTED(TransactionDefinition.PROPAGATION_NESTED);
private final int value;
Propagation(int value) { this.value = value; }
public int value() { return this.value; }
}
public enum Isolation {
DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
private final int value;
Isolation(int value) { this.value = value; }
public int value() { return this.value; }
}5.3 注解解析流程(完整链路)
@Transactional 注解
↓
TransactionManagementConfigurationSelector
(@EnableTransactionManagement 触发导入)
↓
ProxyTransactionManagementConfiguration
(注册 AOP 基础设施)
↓
TransactionInterceptor(MethodInterceptor)
↓
invokeWithinTransaction()
↓
PlatformTransactionManager.getTransaction()
↓
AbstractPlatformTransactionManager.handleTransactionPropagation()
(传播行为分发)
↓
doBegin() / 挂起 / 创建保存点5.3.1 入口:@EnableTransactionManagement
@EnableTransactionManagement 是启用声明式事务的门户注解:
package org.springframework.transaction.annotation;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
// 是否使用 CGLIB 代理(true=类代理,false=接口代理)
boolean proxyTargetClass() default false;
// 通知模式:PROXY(默认,只能拦截外部方法调用)
AdviceMode mode() default AdviceMode.PROXY;
// 执行顺序,默认最后执行
int order() default Ordered.LOWEST_PRECEDENCE;
}5.3.2 TransactionManagementConfigurationSelector
package org.springframework.transaction.annotation;
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
// 注册 AutoProxyRegistrar + ProxyTransactionManagementConfiguration
return new String[] {
AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()
};
case ASPECTJ:
// AspectJ 模式(编译期织入)
return new String[] {
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
};
default:
return null;
}
}
}5.3.3 ProxyTransactionManagementConfiguration——注册事务拦截器
package org.springframework.transaction.annotation;
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
/**
* 注册 TransactionInterceptor Bean——事务拦截的核心
*/
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource,
TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor =
new BeanFactoryTransactionAttributeSourceAdvisor();
// 设置事务属性解析器:用于从 @Transactional 提取属性
advisor.setTransactionAttributeSource(transactionAttributeSource);
// 设置拦截器
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
/**
* 注册事务属性解析器——解析 @Transactional 注解
*/
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
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;
}
}5.3.4 TransactionInterceptor——AOP 拦截入口
package org.springframework.transaction.interceptor;
public class TransactionInterceptor extends TransactionAspectSupport
implements MethodInterceptor, Serializable {
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null
? AopUtils.getTargetClass(invocation.getThis()) : null);
// 委派给父类的模板方法
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
}5.3.5 TransactionAspectSupport.invokeWithinTransaction——核心模板方法
package org.springframework.transaction.interceptor;
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// 步骤1:获取事务属性源,解析 @Transactional 注解
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 步骤2:根据 @Transactional 的 transactionManager 属性查找 PlatformTransactionManager
// 如果未指定,默认查找类型为 PlatformTransactionManager 且名为 "transactionManager" 的 Bean
final TransactionManager tm = determineTransactionManager(txAttr);
// 步骤3:构建目标方法标识(用于日志和监控)
String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// === 声明式事务处理逻辑 ===
if (txAttr == null || !(tm instanceof PlatformTransactionManager)) {
// 非事务执行或 ReactiveTransactionManager 走其他路径
return invokeWithinTransactionUsingReactiveAdapter(method, targetClass, invocation, txAttr, tm);
}
// 转型为命令式事务管理器
PlatformTransactionManager ptm = (PlatformTransactionManager) tm;
// 步骤4:构建 TransactionInfo(保存事务状态、属性、管理器等信息)
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// 步骤5:执行目标方法(执行业务逻辑)
retVal = invocation.proceedWithInvocation();
} catch (Throwable ex) {
// 步骤6:异常时根据事务属性判断是否回滚
// - rollbackFor 指定的异常 → 回滚
// - RuntimeException / Error → 回滚
// - 受检异常 → 提交(默认不回滚)
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
// 步骤7:清理事务信息(恢复挂起的事务)
cleanupTransactionInfo(txInfo);
}
// 步骤8:正常提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
/**
* 创建事务(如果需要)
*/
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
// 如果没有 @Transactional 属性,使用默认定义
TransactionAttribute txAttrToUse = txAttr;
if (txAttr == null) {
txAttrToUse = new DefaultTransactionAttribute(joinpointIdentification);
}
// 获取 PlatformTransactionManager
PlatformTransactionManager tmToUse = tm;
if (tmToUse == null) {
// 从 BeanFactory 查找
tmToUse = getTransactionManager(txAttrToUse, joinpointIdentification);
}
// === 核心调用:创建事务 ===
TransactionStatus status = tmToUse.getTransaction(txAttrToUse);
// 构建 TransactionInfo 对象,封装事务状态
return prepareTransactionInfo(tmToUse, txAttrToUse, joinpointIdentification, status);
}
}5.4 异常回滚判定逻辑
// TransactionAspectSupport.completeTransactionAfterThrowing
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
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;
}
} else {
// 不满足回滚条件 → 仍然提交
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
}
}
}
// RuleBasedTransactionAttribute.rollbackOn —— 回滚判定规则
public boolean rollbackOn(Throwable ex) {
// 从 @Transactional 的 rollbackFor / noRollbackFor 中提取的规则
if (this.rollbackRules != null) {
for (RollbackRule rule : this.rollbackRules) {
if (rule instanceof NoRollbackRuleAttribute) {
// noRollbackFor:如果匹配则不回滚
if (rule.getDepth(ex) > 0) return false;
} else {
// rollbackFor:如果匹配则回滚
if (rule.getDepth(ex) > 0) return true;
}
}
}
// 默认规则:RuntimeException 和 Error 回滚,受检异常提交
return ex instanceof RuntimeException || ex instanceof Error;
}六、7 种事务传播行为详解
6.1 概念速览
| 传播行为 | 常量值 | 语义概要 |
|---|---|---|
REQUIRED | 0 | 支持当前事务,无则新建 |
SUPPORTS | 1 | 支持当前事务,无则非事务执行 |
MANDATORY | 2 | 必须在事务中执行,无则抛异常 |
REQUIRES_NEW | 3 | 总是新建事务,挂起当前事务 |
NOT_SUPPORTED | 4 | 以非事务方式执行,挂起当前事务 |
NEVER | 5 | 以非事务方式执行,有事务抛异常 |
NESTED | 6 | 嵌套事务(基于保存点) |
6.2 REQUIRED —— 默认传播行为
语义:支持当前事务;如果当前没有事务,则创建一个新事务。
行为演示:
@Service
public class UserService {
@Autowired
private AccountService accountService;
@Transactional(propagation = Propagation.REQUIRED)
public void transfer(Long fromId, Long toId, BigDecimal amount) {
// 方法 A:开启事务 TxA
accountService.debit(fromId, amount);
// 调用方法 B
accountService.credit(toId, amount);
// TxA 在此方法返回时提交
}
}
@Service
public class AccountService {
@Transactional(propagation = Propagation.REQUIRED)
public void debit(Long accountId, BigDecimal amount) {
// 方法 B:加入 TxA(不创建新事务)
jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE id = ?",
amount, accountId);
}
@Transactional(propagation = Propagation.REQUIRED)
public void credit(Long accountId, BigDecimal amount) {
// 方法 C:加入 TxA(不创建新事务)
jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE id = ?",
amount, accountId);
}
}执行流程:
transfer() 调用 → 无事务 → 创建 TxA
└→ debit() → 已有 TxA → 加入 TxA
└→ credit() → 已有 TxA → 加入 TxA
transfer() 返回 → 提交 TxA关键特征:
- 多个方法共享同一个物理事务
- 任何一个方法抛出导致回滚的异常,整个事务回滚
- 如果外围方法已存在事务,则内层方法直接参与
6.3 SUPPORTS
语义:支持当前事务;如果当前没有事务,则以非事务方式执行。
@Transactional(propagation = Propagation.SUPPORTS)
public void queryUser(Long id) {
// 有事务则参与,没有则不开启事务
return userRepository.findById(id);
}典型场景:查询方法。有事务时利用事务的隔离性(例如可重复读),没有事务时也可以执行。
6.4 MANDATORY
语义:强制要求在事务中执行;如果当前没有事务,则抛出 IllegalTransactionStateException。
@Transactional(propagation = Propagation.MANDATORY)
public void deductFee(Long orderId) {
// 必须在已有事务中执行
jdbcTemplate.update("UPDATE orders SET fee = fee - ? WHERE id = ?", orderId);
}典型场景:该方法不允许单独被调用,必须作为某个完整业务操作的一部分存在。
6.5 REQUIRES_NEW
语义:总是启动一个新事务;如果当前存在事务,则将当前事务挂起(suspend)。
@Service
public class OrderService {
@Autowired
private AuditLogService auditLogService;
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
// TxA:创建订单
jdbcTemplate.update("INSERT INTO orders ...");
// 无论 TxA 是否成功,审计日志都要记录
auditLogService.log("Order created: " + order.getId());
}
}
@Service
public class AuditLogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void log(String message) {
// 启动新事务 TxB,挂起 TxA
jdbcTemplate.update("INSERT INTO audit_log (message) VALUES (?)", message);
// TxB 在此方法返回时提交
// 之后 TxA 恢复
}
}执行流程:
createOrder() 调用 → 无事务 → 创建 TxA
└→ log() 调用 → 存在 TxA → 挂起 TxA → 创建 TxB
└→ log() 返回 → 提交 TxB → 恢复 TxA
createOrder() 返回 → 提交 TxA(或回滚)关键特征:
- 内外事务完全独立,互不影响
- 内层事务提交不依赖外层事务
- 外层事务回滚不影响内层已提交的事务结果
- 需要底层资源支持事务挂起(通常是通过持有两个不同 Connection 实现)
6.6 NOT_SUPPORTED
语义:以非事务方式执行;如果当前存在事务,则将当前事务挂起。
@Transactional(propagation = Propagation.REQUIRED)
public void process() {
// TxA:事务中处理业务
updateData();
// 发送通知不需要事务
notificationService.send("Process completed");
}
@Service
public class NotificationService {
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void send(String message) {
// 挂起 TxA,非事务执行
mailSender.send(message);
// 方法返回后,TxA 恢复
}
}6.7 NEVER
语义:以非事务方式执行;如果当前存在事务,则抛出 IllegalTransactionStateException。
@Transactional(propagation = Propagation.NEVER)
public void cleanCache() {
// 清理缓存操作不应该在事务中执行
cacheManager.evictAll();
}6.8 NESTED
语义:如果当前存在事务,则在嵌套事务(基于保存点/Savepoint)中执行;如果没有事务,则行为同 REQUIRED。
@Service
public class BatchService {
@Autowired
private ItemService itemService;
@Transactional(propagation = Propagation.REQUIRED)
public void batchProcess(List<Item> items) {
for (Item item : items) {
try {
itemService.processItem(item); // NESTED 传播行为
} catch (Exception ex) {
// 捕获单个条目的异常,不影响其他条目
log.error("Item {} failed: {}", item.getId(), ex.getMessage());
}
}
}
}
@Service
public class ItemService {
@Transactional(propagation = Propagation.NESTED)
public void processItem(Item item) {
// 在嵌套事务(保存点)中执行
jdbcTemplate.update("UPDATE items SET status = ? WHERE id = ?",
item.getStatus(), item.getId());
}
}执行流程:
batchProcess() → 创建 TxA
└→ processItem(item1) → 创建保存点 SP1 → 执行操作
├── 成功 → 释放 SP1
└── 失败 → 回滚到 SP1(TxA 整体未回滚)
└→ processItem(item2) → 创建保存点 SP2 → 执行操作
...
batchProcess() → 提交 TxA(所有成功的嵌套子事务一起提交)与 REQUIRES_NEW 的关键区别:
| 特性 | REQUIRES_NEW | NESTED |
|---|---|---|
| 事务独立性 | 完全独立,各自提交/回滚 | 依赖于外层事务 |
| 底层实现 | 挂起+新连接/新事务 | JDBC 3.0 Savepoint |
| 内层回滚影响 | 不影响外层 | 回滚到保存点,外层可继续 |
| 内层提交时间 | 内层返回即提交 | 随外层一起提交 |
| 资源消耗 | 高(额外连接) | 低(同一连接) |
七、5 种事务隔离级别详解
7.1 事务并发问题
在了解隔离级别前,需要先了解事务并发执行时可能出现的三种问题:
| 问题 | 描述 | 示例 |
|---|---|---|
| 脏读 | 读到其他事务未提交的数据 | 事务 A 修改 id=1 → balance=1000(未提交),事务 B 读到 1000;事务 A 回滚 → B 读到的是"脏数据" |
| 不可重复读 | 同一事务中两次读取同一行数据结果不同(行内容变化) | 事务 A 第一次读 balance=500,事务 B 修改 balance=600 并提交,事务 A 第二次读 balance=600 |
| 幻读 | 同一事务中两次查询返回不同的行集合(行数变化) | 事务 A 查询余额>100 的记录数=5,事务 B 插入一条新记录并提交,事务 A 再次查询记录数=6 |
7.2 各隔离级别对比
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现机制 |
|---|---|---|---|---|
DEFAULT | 取决于数据库 | 取决于数据库 | 取决于数据库 | 使用数据库默认级别 |
READ_UNCOMMITTED | 可能 | 可能 | 可能 | 根本不加锁 |
READ_COMMITTED | 防止 | 可能 | 可能 | 读不加锁/写加行锁(MVCC 快照读) |
REPEATABLE_READ | 防止 | 防止 | 可能(MySQL InnoDB 通过间隙锁防止) | 读加行锁/写加行锁(MVCC 快照读) |
SERIALIZABLE | 防止 | 防止 | 防止 | 范围锁/表锁,完全串行化 |
7.3 数据库默认隔离级别
| 数据库 | 默认隔离级别 |
|---|---|
| MySQL (InnoDB) | REPEATABLE_READ |
| PostgreSQL | READ_COMMITTED |
| Oracle | READ_COMMITTED |
| SQL Server | READ_COMMITTED |
| H2 | READ_COMMITTED |
7.4 隔离级别的 JDBC 支持
// java.sql.Connection 定义的隔离级别常量
public interface Connection {
int TRANSACTION_NONE = 0; // 不支持事务
int TRANSACTION_READ_UNCOMMITTED = 1;
int TRANSACTION_READ_COMMITTED = 2;
int TRANSACTION_REPEATABLE_READ = 4;
int TRANSACTION_SERIALIZABLE = 8;
}7.5 Spring 设置隔离级别
// 方式一:注解
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void processOrder(Long orderId) { ... }
// 方式二:编程式
TransactionTemplate template = new TransactionTemplate(transactionManager);
template.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
template.execute(status -> {
// 事务代码
return null;
});八、AbstractPlatformTransactionManager.handleTransactionPropagation() 源码分析
这是 AbstractPlatformTransactionManager 中最核心的方法,它实现了传播行为的分发逻辑。