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

Spring 事务机制深度解析

本文档基于对 Spring Framework 源码的深入分析,详细阐述了 Spring 事务的管理机制、核心流程以及与 JDBC/JPA 的交互细节。


1. 核心架构组件

Spring 事务管理采用策略模式模板方法模式相结合的设计,主要包含以下核心组件:

组件职责
PlatformTransactionManager事务管理器接口,定义了getTransaction,commit,rollback等核心操作。
TransactionDefinition事务定义,包含传播行为、隔离级别、超时时间、只读标志等属性。
TransactionStatus事务状态,记录当前事务是否为新事务、是否已完成、是否标记为回滚等。
TransactionInterceptorAOP 拦截器,负责在方法调用前后织入事务逻辑。
TransactionSynchronizationManager使用ThreadLocal管理当前线程绑定的资源(如 Connection)和同步回调。

2. 事务生命周期与调用链路

2.1 完整调用流程

当一个带有@Transactional注解的方法被调用时,执行流程如下:

  1. AOP 拦截:TransactionInterceptor.invoke()捕获方法调用。
  2. 获取事务属性: 解析方法或类上的@Transactional注解,生成TransactionAttribute(txAttr)。
  3. 创建/加入事务: 调用createTransactionIfNecessary()
    • txAttr == null,直接执行业务逻辑,不走事务流程。
    • txAttr != null,调用PlatformTransactionManager.getTransaction()
  4. 开启事务 (doBegin):
    • 如果需要新事务,调用DataSourceTransactionManager.doBegin()
    • 获取数据库连接,设置autocommit = false
    • 将连接绑定到TransactionSynchronizationManager
  5. 执行业务逻辑: 调用目标方法(如 Service 中的业务代码)。
  6. 提交/回滚:
    • 成功: 调用commitTransactionAfterReturning()->doCommit()->con.commit()
    • 异常: 调用completeTransactionAfterThrowing()->doRollback()->con.rollback()
  7. 清理资源: 解绑连接,恢复autocommit状态,归还连接池。

2.2 doBegin() 的调用时机

doBegin()不会在以下情况调用:

  • 方法没有@Transactional注解 (txAttr == null)。
  • 传播行为为SUPPORTS且当前无事务。
  • 传播行为为NOT_SUPPORTED
  • 传播行为为REQUIRED但当前已存在事务(此时会加入现有事务)。

doBegin()在以下情况调用:

  • 传播行为为REQUIRED/REQUIRES_NEW/NESTED
  • 且当前线程没有活跃的事务(或者REQUIRES_NEW强制挂起旧事务开启新的)。

3. 无事务注解时的行为分析

3.1 纯 JDBC (JdbcTemplate) 场景

如果 Service 方法和 Repository 均未添加@Transactional

  • 事务管理: Spring不介入事务管理,doBegin()不会被调用。
  • 连接获取: 每次数据库操作都会从连接池获取一个新连接。
  • 提交机制: 依赖 JDBC 驱动的Auto-Commit机制。
    • Connection.getAutoCommit()默认为true
    • 每条 SQL 执行完毕后,JDBC 驱动会自动向数据库发送COMMIT
  • 后果: 每条 SQL 都是一个独立的原子操作,无法保证多条操作之间的原子性。

3.2 Spring Data JPA (Repository) 场景

如果 Service 方法未加@Transactional,但调用了userRepository.save()

  • 隐式事务: Spring Data JPA 的默认实现类SimpleJpaRepositorysave()方法上标注了@Transactional
  • 调用位置:doBegin()会在Repository 层被调用。
  • 执行流程:
    1. Service 调用repository.save()
    2. AOP 拦截SimpleJpaRepository.save()
    3. 发现注解,触发doBegin(),开启一个短事务。
    4. 执行em.persist(),SQL 在事务提交前 Flush。
    5. 方法结束,触发doCommit()
  • 后果: 虽然单条保存有事务保障,但 Service 层多次调用 Repository 时,每次调用都是独立的事务。如果中间发生异常,之前已提交的 Repository 操作无法回滚

4. 关键设计思想

4.1 声明式事务 (Declarative Transaction)

通过 AOP 将事务逻辑与业务逻辑解耦。开发者只需添加注解,无需手动编写begin/commit/rollback代码。

4.2 资源绑定 (Resource Binding)

利用ThreadLocal确保同一个事务内的所有数据库操作使用同一个 Connection。这是实现事务原子性的基础。

4.3 延迟提交 (Lazy Commit)

在事务开启后,SQL 执行并不会立即提交到数据库,而是等到业务方法成功执行完毕,由 Spring 统一调用con.commit()

4.4 异常驱动回滚

默认情况下,只有遇到RuntimeExceptionError时才会触发回滚。Checked Exception 默认不回滚,除非显式配置rollbackFor


5. 常见误区澄清

误区真相
没加注解,SQL 就不会执行SQL 会正常执行,并通过 Auto-Commit 立即持久化。
Spring 会自动为所有方法加事务Spring 遵循“显式优于隐式”,必须显式添加注解或配置。
Repository 层的 save 总是安全的如果 Service 层没事务,Repository 的 save 只是单条 SQL 的原子,无法保证业务层面的原子性。
txAttr 为 null 时也会调用 doBegin绝对不会。txAttr == null是事务拦截的第一道防线,直接跳过事务逻辑。

6. 总结

Spring 事务的核心在于AOP 拦截Connection 资源的线程绑定

  • 有注解时: Spring 接管连接,关闭 Auto-Commit,统一控制提交与回滚。
  • 无注解时: 回归 JDBC 默认行为,依赖 Auto-Commit,每条 SQL 独立提交。

在实际开发中,为了保证业务数据的 consistency(一致性),建议在Service 层的入口方法上添加@Transactional,以确保整个业务单元作为一个完整的事务执行。

http://www.jsqmd.com/news/873030/

相关文章:

  • 创业公司如何利用Taotoken多模型能力低成本构建AI产品原型
  • Meta Ads AI Connectors:怎么通过 MCP 把 Claude 接入 Ads Manager
  • CPU压力测试
  • mysql从5.7升级到8.0后ONLY_FULL_GROUP_BY是升级后应用报错的第一大原因
  • 高中化学中过氧化物+过硫化物
  • 2026年丽水AI搜索优化公司横向评测:五强避坑与选型全攻略 - 品牌报告
  • Fish Audio(鱼声)+ Python:零门槛用自己声音合成任何文本
  • Claude插件报错急救指南:从诊断到修复的完整解决方案
  • 谷歌I/O 2026重磅发布:Gemini 3.5 Flash上线、Spark全天候AI代理来了
  • 如何通过NVIDIA Profile Inspector深度优化游戏性能:解锁显卡隐藏设置的完整指南
  • 如何在5分钟内快速部署LaWGPT法律大模型:中文法律AI的完整实战指南
  • DDD 与 Ontology 对比分析:哪一种更适合AI时代复杂系统构建?
  • VonaJS全栈框架5.1.34发布:DTO配字段生成CRUD页面,对比Django Admin、NestJS优势显著!
  • Windows安卓应用安装器:告别繁琐模拟器,电脑直接运行手机应用
  • Poppler Windows版:终极PDF处理方案,3分钟零配置部署指南
  • 2026论文降AIGC率攻略:5款工具实测及避坑指南
  • AI进行简历筛选:如何将5小时筛选压缩至48分钟,彻底解决“招错人“难题?
  • 气象水文耦合模式WRF-Hydro建模技术应用
  • Taotoken的Token Plan套餐如何帮助初创团队控制AI成本
  • 【收藏干货】2026 版 11 款主流 AI Agent 框架全方位对比!程序员小白入门大模型必备选型指南
  • Beyond Compare 5密钥生成器:从评估到期到永久授权的完整解决方案
  • 为什么很多企业买三维扫描设备之前问“多少钱”,用了一段时间后开始问“值不值”?
  • QuickAPI入门:5分钟发布你的第一个数据API
  • 导览机器人产品讲解(摄像头 + YOLO 真实识别 + 语音讲解)
  • 2026企业新媒体营销培训机构推荐:飞橙教育实战课程因何成为口碑之选
  • ACS770还能打吗?最近测试了一款国产霍尔电流传感器
  • 不会 CSS 也能做出惊艳 PPT!Frontend Slides这个开源 Claude Code 技能让 AI 帮你生成 12 种风格演示文稿,告别千篇一律的紫渐变
  • 3K档位的四盘位“六边形战士”?绿联DXP4800 GT深度体验
  • 香港6月雨季来临,房屋漏水怎么办?卫生间免砸砖防水、外墙、屋面+地下室渗漏。权威防水公司靠谱TOP5推荐(2026年6月本地最新深度调研) - 企业资讯
  • 学习笔记·敏捷开发