本文档基于对 Spring Framework 源码的深入分析详细阐述了 Spring 事务的管理机制、核心流程以及与 JDBC/JPA 的交互细节。1. 核心架构组件Spring 事务管理采用策略模式与模板方法模式相结合的设计主要包含以下核心组件组件职责PlatformTransactionManager事务管理器接口定义了getTransaction,commit,rollback等核心操作。TransactionDefinition事务定义包含传播行为、隔离级别、超时时间、只读标志等属性。TransactionStatus事务状态记录当前事务是否为新事务、是否已完成、是否标记为回滚等。TransactionInterceptorAOP 拦截器负责在方法调用前后织入事务逻辑。TransactionSynchronizationManager使用ThreadLocal管理当前线程绑定的资源如 Connection和同步回调。2. 事务生命周期与调用链路2.1 完整调用流程当一个带有Transactional注解的方法被调用时执行流程如下AOP 拦截:TransactionInterceptor.invoke()捕获方法调用。获取事务属性: 解析方法或类上的Transactional注解生成TransactionAttribute(txAttr)。创建/加入事务: 调用createTransactionIfNecessary()。若txAttr null直接执行业务逻辑不走事务流程。若txAttr ! null调用PlatformTransactionManager.getTransaction()。开启事务 (doBegin):如果需要新事务调用DataSourceTransactionManager.doBegin()。获取数据库连接设置autocommit false。将连接绑定到TransactionSynchronizationManager。执行业务逻辑: 调用目标方法如 Service 中的业务代码。提交/回滚:成功: 调用commitTransactionAfterReturning()-doCommit()-con.commit()。异常: 调用completeTransactionAfterThrowing()-doRollback()-con.rollback()。清理资源: 解绑连接恢复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 的默认实现类SimpleJpaRepository的save()方法上标注了Transactional。调用位置:doBegin()会在Repository 层被调用。执行流程:Service 调用repository.save()。AOP 拦截SimpleJpaRepository.save()。发现注解触发doBegin()开启一个短事务。执行em.persist()SQL 在事务提交前 Flush。方法结束触发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 异常驱动回滚默认情况下只有遇到RuntimeException或Error时才会触发回滚。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以确保整个业务单元作为一个完整的事务执行。