Spring 事务传播机制源码深度解析
Spring 事务传播机制是处理嵌套事务的核心逻辑,它定义了事务方法相互调用时事务的边界行为。本文将从源码层面深入剖析 Spring 事务传播机制的实现原理,通过关键类和方法解析揭示其内部工作机制。
一、传播机制的核心入口:getTransaction()
AbstractPlatformTransactionManager.getTransaction()
方法是传播机制的总入口,负责根据传播行为决定事务的创建、加入或挂起:
public final TransactionStatus getTransaction(TransactionDefinition definition) {
// 1. 获取当前事务对象(数据源相关)
Object transaction = doGetTransaction();
// 2. 检查是否存在现有事务
if (isExistingTransaction(transaction)) {
// 存在事务:根据传播行为处理
return handleExistingTransaction(definition, transaction);
}
// 3. 不存在事务:根据传播行为创建新事务
return startTransaction(definition, transaction);
}
二、存在事务时的处理:handleExistingTransaction()
当检测到当前已存在事务时,Spring 会根据不同的传播行为采取不同策略:
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction) {
// 1. NEVER:禁止在事务中运行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
// 2. NOT_SUPPORTED:挂起当前事务,非事务执行
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
Object suspendedResources = suspend(transaction);
return prepareTransactionStatus(
definition, null, false, false, suspendedResources);
}
// 3. REQUIRES_NEW:挂起当前事务,创建新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
return startTransaction(definition, transaction, suspendedResources);
} catch (RuntimeException | Error ex) {
resumeAfterException(transaction, suspendedResources, ex);
throw ex;
}
}
// 4. NESTED:创建嵌套事务(保存点)
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(...);
}
Object savepoint = createSavepoint();
return prepareTransactionStatus(
definition, transaction, false, true, savepoint);
}
// 5. 默认行为(REQUIRED, SUPPORTS, MANDATORY):加入当前事务
return prepareTransactionStatus(
definition, transaction, false, false);
}
三、关键传播行为源码解析
1. REQUIRES_NEW 传播行为
// 挂起当前事务
protected final SuspendedResourcesHolder suspend(Object transaction) {
// 1. 解绑当前线程的事务资源
List<TransactionSynchronization> suspendedSynchronizations = null;
if (TransactionSynchronizationManager.isSynchronizationActive()) {
suspendedSynchronizations = TransactionSynchronizationManager.getSynchronizations();
TransactionSynchronizationManager.clearSynchronization();
}
// 2. 解绑事务资源(如数据库连接)
Map<Object, Object> suspendedResources = new HashMap<>();
for (Map.Entry<Object, Object> entry : resources.entrySet()) {
Object key = entry.getKey();
Object value = suspendResource(key);
if (value != null) {
suspendedResources.put(key, value);
}
}
// 3. 返回挂起资源持有器
return new SuspendedResourcesHolder(
transaction, suspendedResources, suspendedSynchronizations);
}
// 创建新事务
private TransactionStatus startTransaction(
TransactionDefinition definition, Object transaction,
SuspendedResourcesHolder suspendedResources) {
// 1. 开启新事务
doBegin(transaction, definition);
// 2. 准备事务状态(标记为新事务)
return prepareTransactionStatus(
definition, transaction, true, false, suspendedResources);
}
2. NESTED 传播行为
// 创建保存点
protected Object createSavepoint() {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(dataSource);
try {
// 通过数据库连接创建保存点
return conHolder.createSavepoint();
} catch (SQLException ex) {
throw new CannotCreateSavepointException("Could not create savepoint", ex);
}
}
// 嵌套事务状态
public class NestedTransactionStatus extends DefaultTransactionStatus {
private final Object savepoint;
public NestedTransactionStatus(
Object transaction, boolean newTransaction, Object savepoint) {
super(transaction, newTransaction, false);
this.savepoint = savepoint;
}
public boolean hasSavepoint() {
return (this.savepoint != null);
}
public Object getSavepoint() {
return this.savepoint;
}
}
3. 嵌套事务回滚处理
protected void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
if (status.hasSavepoint()) {
// 嵌套事务:回滚到保存点
status.rollbackToHeldSavepoint();
} else if (status.isNewTransaction()) {
// 新事务:完全回滚
doRollback(status);
} else if (status.hasTransaction()) {
// 加入的事务:标记为回滚
doSetRollbackOnly(status);
}
} finally {
// 清理资源
cleanupAfterCompletion(status);
}
}
四、事务资源绑定机制
Spring 通过 TransactionSynchronizationManager
实现线程级事务资源绑定:
public abstract class TransactionSynchronizationManager {
// 线程局部变量存储事务资源
private static final ThreadLocal<Map<Object, Object>> resources =
new NamedThreadLocal<>("Transactional resources");
// 绑定资源到当前线程
public static void bindResource(Object key, Object value) {
Map<Object, Object> map = resources.get();
if (map == null) {
map = new HashMap<>();
resources.set(map);
}
Object oldValue = map.put(key, value);
if (oldValue != null) {
throw new IllegalStateException("Already value [" + oldValue + "] for key [" + key + "]");
}
}
// 从当前线程解绑资源
public static Object unbindResource(Object key) {
Map<Object, Object> map = resources.get();
if (map == null) {
return null;
}
Object value = map.remove(key);
if (map.isEmpty()) {
resources.remove();
}
return value;
}
}
五、传播行为执行流程图解
六、传播机制与事务同步器
Spring 提供了 TransactionSynchronization
接口,允许在事务生命周期中插入自定义逻辑:
public interface TransactionSynchronization {
// 事务挂起时调用
void suspend();
// 事务恢复时调用
void resume();
// 事务提交前调用(可访问事务资源)
void beforeCommit(boolean readOnly);
// 事务完成前调用(资源已关闭)
void beforeCompletion();
// 事务提交后调用
void afterCommit();
// 事务最终完成时调用
void afterCompletion(int status);
}
同步器注册与触发
public abstract class AbstractPlatformTransactionManager {
// 提交事务时触发同步器
private void triggerBeforeCommit(DefaultTransactionStatus status) {
if (status.isNewSynchronization()) {
for (TransactionSynchronization synchronization :
TransactionSynchronizationManager.getSynchronizations()) {
synchronization.beforeCommit(status.isReadOnly());
}
}
}
// 事务完成后触发同步器
private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) {
if (status.isNewSynchronization()) {
for (TransactionSynchronization synchronization :
TransactionSynchronizationManager.getSynchronizations()) {
synchronization.afterCompletion(completionStatus);
}
}
}
}
七、传播机制在分布式事务中的扩展
Spring 通过 JtaTransactionManager
扩展传播机制支持分布式事务:
public class JtaTransactionManager extends AbstractPlatformTransactionManager {
@Override
protected Object doGetTransaction() {
// 获取 JTA 事务
Transaction tx = getTransactionManager().getTransaction();
return new JtaTransactionObject(tx);
}
@Override
protected boolean isExistingTransaction(Object transaction) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
return (txObject.getTransaction() != null);
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
// 开启 JTA 事务
getTransactionManager().begin();
}
// 处理 REQUIRES_NEW 传播行为
@Override
protected Object doSuspend(Object transaction) {
// 挂起 JTA 事务
return getTransactionManager().suspend();
}
@Override
protected void doResume(Object transaction, Object suspendedResources) {
// 恢复 JTA 事务
getTransactionManager().resume((Transaction) suspendedResources);
}
}
八、最佳实践与性能优化
1. 传播行为选择建议
业务场景 | 推荐传播行为 | 说明 |
---|---|---|
核心业务操作 | REQUIRED | 默认行为,加入或创建事务 |
独立日志记录 | REQUIRES_NEW | 确保日志记录独立提交 |
批量处理子项 | NESTED | 子项失败不影响整体 |
非关键操作 | NOT_SUPPORTED | 避免事务开销 |
强制事务环境 | MANDATORY | 确保在事务中执行 |
2. 性能优化策略
避免不必要的挂起操作:
// 优化前:频繁挂起/恢复事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logOperation(String message) {
// 日志记录
}
// 优化后:批量处理减少挂起
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void batchLogOperations(List<String> messages) {
for (String msg : messages) {
logService.log(msg);
}
}
合理使用只读事务:
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public Report generateReport() {
// 复杂查询操作
}
九、总结
Spring 事务传播机制的核心实现要点:
- 入口在
getTransaction()
:统一处理事务创建逻辑 - 传播行为决策树:通过
handleExistingTransaction()
实现不同传播策略 - 资源绑定机制:使用
TransactionSynchronizationManager
管理线程级资源 - 嵌套事务实现:基于数据库保存点(Savepoint)实现
- 分布式事务扩展:通过
JtaTransactionManager
支持 JTA
深入理解传播机制源码,有助于开发者:
- 合理选择传播行为满足业务需求
- 优化事务性能避免资源浪费
- 排查复杂事务场景中的问题
- 扩展自定义事务管理逻辑
- 设计高效的事务处理方案
通过源码分析可见,Spring 事务传播机制的设计充分考虑了各种业务场景的需求,提供了灵活而强大的事务管理能力,是构建高可靠企业应用的重要基础。