当前位置: 首页 > news >正文

Spring事务融入(REQUIRED)具体实现步骤解析

Spring事务融入(REQUIRED传播行为)是Spring事务管理中最核心的机制,下面我将深入剖析其具体实现步骤和关键代码逻辑。

1. 整体流程概览

事务融入(REQUIRED)的核心逻辑是:

  1. 检查当前线程是否存在事务

  2. 存在则融入(加入)该事务

  3. 不存在则创建新事务

2. 详细实现步骤

步骤1:事务获取入口

@Transactional注解或编程式事务调用开始,最终会进入PlatformTransactionManager的实现类:

// AbstractPlatformTransactionManager.java
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) {// 获取或创建事务对象Object transaction = doGetTransaction();// 检查是否存在事务if (isExistingTransaction(transaction)) {// 存在事务则处理融入逻辑return handleExistingTransaction(def, transaction, debugEnabled);}// 不存在事务则创建新事务return startTransaction(def, transaction, debugEnabled, suspendedResources);
}

步骤2:判断是否存在事务

以DataSourceTransactionManager为例:

// DataSourceTransactionManager.java
@Override
protected boolean isExistingTransaction(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;// 关键判断:连接持有者不为null且连接已开启事务return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}

步骤3:处理已存在事务(融入核心)

// AbstractPlatformTransactionManager.java
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled) {// 1. 处理NEVER传播行为if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {throw new IllegalTransactionStateException(...);}// 2. 处理NOT_SUPPORTED传播行为(挂起现有事务)if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {Object suspendedResources = suspend(transaction);return prepareTransactionStatus(...);}// 3. 处理REQUIRES_NEW传播行为(挂起并新建)if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {SuspendedResourcesHolder suspendedResources = suspend(transaction);return startTransaction(definition, transaction, debugEnabled, suspendedResources);}// 4. 处理NESTED传播行为(创建保存点)if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {if (!isNestedTransactionAllowed()) {throw new NestedTransactionNotSupportedException(...);}Object savepoint = createSavepoint(transaction);return prepareTransactionStatus(...);}// 5. 默认处理REQUIRED/SUPPORTS/MANDATORY(融入现有事务)if (debugEnabled) {logger.debug("Participating in existing transaction");}// 关键点:设置"新事务"标志为false,表示融入现有事务return prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
}

步骤4:准备事务状态(融入关键)

// AbstractPlatformTransactionManager.java
protected final DefaultTransactionStatus prepareTransactionStatus(TransactionDefinition definition, Object transaction, boolean newTransaction, boolean newSynchronization,boolean debug, @Nullable Object suspendedResources) {// 创建事务状态对象DefaultTransactionStatus status = newTransactionStatus(definition, transaction, newTransaction, newSynchronization,debug, suspendedResources);// 初始化事务同步(重要!)prepareSynchronization(status, definition);return status;
}

步骤5:事务同步准备

// AbstractPlatformTransactionManager.java
protected void prepareSynchronization(DefaultTransactionStatus status,TransactionDefinition definition) {if (status.isNewSynchronization()) {// 初始化新事务的同步器TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(definition.getIsolationLevel());TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());// 初始化同步回调列表TransactionSynchronizationManager.initSynchronizations();}
}

3. 关键实现技术

3.1 线程绑定机制

Spring通过TransactionSynchronizationManager维护线程绑定资源:

// TransactionSynchronizationManager.java
private static final ThreadLocal<Map<Object, Object>> resources =new NamedThreadLocal<>("Transactional resources");public static void bindResource(Object key, Object value) {Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);Map<Object, Object> map = resources.get();if (map == null) {map = new HashMap<>();resources.set(map);}Object oldValue = map.put(actualKey, value);// 检查是否重复绑定if (oldValue != null) {throw new IllegalStateException(...);}
}

3.2 连接资源管理

DataSourceTransactionManager对Connection的管理:

// DataSourceTransactionManager.java
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;Connection con = null;try {// 获取或创建连接if (!txObject.hasConnectionHolder() || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {Connection newCon = obtainDataSource().getConnection();txObject.setConnectionHolder(new ConnectionHolder(newCon), true);}// 设置事务属性con = txObject.getConnectionHolder().getConnection();Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);// 设置自动提交为falseif (con.getAutoCommit()) {con.setAutoCommit(false);}// 绑定到当前线程bindResource(obtainDataSource(), txObject.getConnectionHolder());}catch (Throwable ex) {// 异常处理...}
}

4. 事务融入的典型场景

场景1:ServiceA调用ServiceB

// ServiceA
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {// 操作1serviceB.methodB(); // 融入同一事务// 操作2
}// ServiceB
@Transactional(propagation = Propagation.REQUIRED)
public void methodB() {// 操作3
}

执行流程

  1. methodA开始时创建新事务

  2. 调用methodB时检测到已有事务,直接融入

  3. 所有操作在同一个物理事务中执行

场景2:跨数据源事务融入

// 主数据源事务
@Transactional("primaryTransactionManager")
public void primaryOperation() {// 操作主库secondaryOperation(); // 调用次数据源操作
}// 次数据源事务
@Transactional("secondaryTransactionManager", propagation = Propagation.REQUIRED)
public void secondaryOperation() {// 操作从库
}

关键点

  • 不同TransactionManager无法真正融入同一事务

  • 实际会创建两个独立事务(需考虑分布式事务方案)

5. 实现注意事项

  1. 连接泄露防护

    • 通过ConnectionHolder跟踪连接状态

    • 事务结束时自动释放连接

  2. 嵌套调用处理

    • 通过事务状态对象跟踪嵌套深度

    • 只有最外层事务实际提交/回滚

  3. 同步回调管理

    • TransactionSynchronization注册回调

    • 保证资源清理顺序正确

  4. 异常处理机制

    • 默认只回滚RuntimeException

    • 可通过@Transactional配置自定义回滚规则

Spring通过这套精密的融入机制,实现了高效的事务管理,既保证了数据一致性,又提供了灵活的配置选项。

相关文章:

  • 游戏引擎学习第269天:清理菜单绘制
  • 互联网大厂Java面试实录:从基础到微服务的深度考察
  • 使用 JAX-RS 创建 REST 服务/微服务
  • 5大B2B数字营销社群营销标杆案例TOB企业数字化营销内容营销AI营销培训讲师培训师专家顾问唐兴通分享
  • KTOR for windows:無文件落地HTTP服务扫描工具
  • SaaS场快订平台项目说明【持续更新】
  • window 显示驱动开发-AGP 类型伸缩空间段
  • [白话文] 从百草园RLHF到三味书屋DPO
  • HTTP 请求中 Content-Type 头部
  • GitHub 趋势日报 (2025年05月09日)
  • 部署dify
  • Web3 实战项目项目部署到 GitHub 和上线预览的完整指南
  • 数据库实验10
  • 多线程获取VI模块的YUV数据
  • ISP(Image Signal Processor)处理流程及不同域划分
  • 【计算机视觉】OpenCV实战项目:Deep Machine Learning Tutors:基于OpenCV的实时面部识别系统深度解析
  • Flink 运维监控与指标采集实战
  • 【前端】每日一道面试题3:如何实现一个基于CSS Grid的12列自适应布局?
  • Spring循环依赖问题
  • 单脉冲前视成像多目标分辨算法——论文阅读
  • 西甲上海足球学院揭幕,用“足球方法论”试水中国青训
  • 巴基斯坦称对印度发起军事行动
  • 上海市委常委会会议暨市生态文明建设领导小组会议研究基层减负、生态环保等事项
  • 上海国际电影节推出三大官方推荐单元,精选十部优秀影片
  • “降息潮”延续!存款利率全面迈向“1时代”
  • 海关总署统计分析司司长:4月进出口增速较一季度加快4.3个百分点