一文讲透 Spring 事务:传播行为、隔离级别与底层原理 Spring 事务的核心作用是保证一组数据库操作要么全部成功要么全部失败。它在数据库事务之上提供了统一抽象使开发者无须直接操作 JDBC 的提交和回滚。一、Spring 事务的类型与管理方式按资源范围划分事务可分为两类本地事务只操作单个数据库或资源常由DataSourceTransactionManager、JpaTransactionManager管理。全局事务协调多个数据库或消息等资源传统方案可使用 JTA。分布式系统中也可能采用 Seata 等方案。按使用方式划分Spring 支持两种事务管理方式编程式事务通过TransactionTemplate或PlatformTransactionManager手动控制灵活但业务代码与事务代码耦合。声明式事务使用Transactional或 XML 配置由 Spring AOP 自动管理。实际开发中更常用。二、七种事务传播行为传播行为解决的问题是一个事务方法调用另一个事务方法时新方法应该加入原事务还是创建新事务传播行为含义REQUIRED有事务就加入没有就新建默认值REQUIRES_NEW挂起当前事务创建独立新事务SUPPORTS有事务就加入没有就以非事务方式运行NOT_SUPPORTED挂起当前事务以非事务方式运行MANDATORY必须存在事务否则抛出异常NEVER必须不存在事务否则抛出异常NESTED在当前事务中创建保存点失败可回滚到保存点高频区别是REQUIRES_NEW创建独立事务内外事务分别提交NESTED通常依赖外部物理事务和保存点外部事务整体回滚时嵌套部分也无法保留。三、Transactional的底层原理Transactional( propagation Propagation.REQUIRED, rollbackFor Exception.class ) public void createOrder() { orderMapper.insertOrder(); stockMapper.deductStock(); }Transactional本身只是事务元数据默认通过 Spring AOP 代理生效。外部调用代理对象时事务拦截器先读取注解配置再通过事务管理器获取数据库连接、关闭自动提交并开启事务。方法正常结束则提交满足回滚规则的异常抛出则回滚。同步事务中Spring 通过ThreadLocal将连接等事务资源绑定到当前线程使同一线程内的多个数据库操作共享同一个事务。最终真正提供原子性、隔离性和持久性的仍是数据库事务机制。因此事务上下文默认不会自动传播到新建线程响应式事务则使用 Reactor Context而非普通ThreadLocal。默认代理模式还存在一个常见问题同一个类中使用this调用另一个Transactional方法会绕过代理导致事务注解失效。四、事务隔离级别Spring 提供五种隔离级别隔离级别作用DEFAULT使用底层数据库的默认隔离级别READ_UNCOMMITTED可能出现脏读、不可重复读和幻读READ_COMMITTED避免脏读REPEATABLE_READ避免脏读和不可重复读SERIALIZABLE串行执行并发能力最低隔离级别越高并发问题越少但锁竞争和性能开销通常越大。MySQL InnoDB 默认是REPEATABLE_READ但 Spring 的DEFAULT并不固定等于该级别而是跟随当前数据库。五、异常出现后是否回滚Transactional默认遇到未被捕获并传播到事务代理之外的RuntimeException或Error会回滚遇到受检异常默认不会回滚。若希望所有业务异常都回滚可以配置Transactional(rollbackFor Exception.class)如果方法内部使用try-catch吞掉异常代理感知不到异常通常会正常提交。此时可以重新抛出异常或调用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()标记回滚。六、JDK 动态代理与 CGLIB在 Spring Framework 的常规代理规则中目标类实现接口时可使用 JDK 动态代理没有实现接口时使用 CGLIB通过生成目标类的子类完成代理。也可以设置proxyTargetClass true强制使用 CGLIB。所以这不是运行时失败后的“降级切换”而是创建代理时根据接口和配置进行选择。CGLIB 无法代理final类也无法增强final、private等不能被子类重写的方法。Spring Boot 的默认代理配置可能与纯 Spring Framework 不同面试时应说明具体环境。七、Spring 5 之后多个 AOP 通知的顺序对一次正常调用可以记成Around 前置 → Before → 目标方法 → AfterReturning → After → Around 后置目标方法抛出异常时AfterThrowing替代AfterReturning。从 Spring 5.2.7 开始同一切面中会可靠地保证AfterReturning或AfterThrowing先于After执行。多个切面之间应通过Order或Ordered明确顺序数值越小进入时越先执行退出时越后执行整体类似过滤器嵌套。不要依赖同一切面中多个同类型通知的方法声明顺序最好拆分切面或显式指定顺序。八、总结Spring 声明式事务以 AOP 代理为入口通过事务管理器控制数据库事务并在线程同步模型下借助ThreadLocal绑定事务资源。Transactional默认传播行为是REQUIRED、隔离级别是DEFAULT未捕获的运行时异常会触发回滚。掌握传播行为、回滚规则、代理边界和 AOP 顺序才能避免“注解写了但事务没有生效”的问题。参考资料Spring 事务注解、Spring 事务抽象、Spring AOP 代理机制。