2026/5/21 15:59:32
网站建设
项目流程
广告片宣传片拍摄公司,做seo要明白网站内容,网站用后台更换图片,ppt免费模板官网Java 外功精要(6)——Spring 事务及其传播机制#xff08;2025-2026 生产级理解版#xff09;
Spring 事务是 Java 后端工程师最常使用、也最容易踩坑的“外功”之一。 尤其是事务传播行为#xff08;Propagation#xff09;#xff0c;面试必考、生产必踩、代码审查必看…Java 外功精要(6)——Spring 事务及其传播机制2025-2026 生产级理解版Spring 事务是 Java 后端工程师最常使用、也最容易踩坑的“外功”之一。尤其是事务传播行为Propagation面试必考、生产必踩、代码审查必看。下面用最清晰的结构 通俗比喻 真实场景把 Spring 事务的核心讲透。一、Spring 事务的核心本质一句话Spring 事务 ≠ 数据库事务Spring 事务是对数据库事务的一种抽象与管理通过 AOP 动态代理在方法执行前后插入 begin/commit/rollback 逻辑。最核心的两句话Spring 事务的边界 被 Transactional 标注的方法或 xml 定义的事务方法事务的传播行为 当方法 A 调用方法 B 时事务应该如何“接力”或“新建”二、Spring 事务的 7 种传播行为Propagation——必背表传播行为Propagation值枚举通俗比喻当外层已有事务时当外层无事务时面试最常问场景实际使用频率2025-2026REQUIREDREQUIRED默认“有饭局就一起吃没饭局就自己开一桌”加入外层事务新建事务99% 普通业务方法★★★★★SUPPORTSSUPPORTS“有饭局就蹭一口没饭局就不吃”加入外层事务不开启新事务不开启事务以非事务方式执行查询方法、日志记录★★★☆☆MANDATORYMANDATORY“必须有饭局才能吃没饭局就报错”加入外层事务抛出异常必须在已有事务中执行的子操作★★☆☆☆REQUIRES_NEWREQUIRES_NEW“不管有没有饭局我都要自己开一桌”挂起外层事务新建独立事务新建事务独立记账、发红包、发站内信、记录操作日志★★★★☆NOT_SUPPORTEDNOT_SUPPORTED“有饭局也先别吃等我吃完再说”挂起外层事务以非事务方式执行非事务执行需要非事务执行的特殊操作如导出报表★★☆☆☆NEVERNEVER“坚决不许有饭局吃就报错”抛出异常非事务执行极少用强制要求不能在事务中执行★☆☆☆☆NESTEDNESTED“在别人饭局里再开一个小灶”如果外层有事务则开启一个嵌套事务保存点外层回滚 → 内层也回滚新建事务保存点场景部分失败仍可提交部分结果★★★☆☆三、最常考、最常踩的 6 种传播行为场景带代码示例ServicepublicclassOrderService{AutowiredprivateOrderDaoorderDao;AutowiredprivateUserServiceuserService;AutowiredprivateLogServicelogService;/** * 场景1默认 REQUIRED最常见 * 下单 → 扣库存 → 扣余额 → 记录日志 */TransactionalpublicvoidcreateOrder(){orderDao.insertOrder();userService.deductBalance();// 加入外层事务logService.writeLog();// 加入外层事务}}ServicepublicclassUserService{/** * 场景2REQUIRES_NEW最常用于独立记录 * 即使外层订单事务回滚发站内信、写操作日志也要成功 */Transactional(propagationPropagation.REQUIRES_NEW)publicvoidsendNotification(){// 发站内信、写操作日志// 即使外层回滚这里也会提交}}ServicepublicclassLogService{/** * 场景3NESTED保存点 * 外层事务中有一部分操作允许失败但整体仍想提交 */Transactional(propagationPropagation.NESTED)publicvoidrecordPartialLog(){// 如果这里抛异常只回滚本方法// 外层事务仍可继续提交已执行部分}}四、事务失效的 8 大经典场景生产必踩面试必考非 public 方法最常见失效原因Transactional 只能标注 public 方法内部调用绕过代理最阴险Transactionalpublicvoidouter(){this.inner();// this 调用绕过代理 → 事务失效}publicvoidinner(){...}解决用 AopContext.currentProxy() 或注入自己事务方法被 private / final / static 修饰数据库不支持事务MyISAM 引擎事务传播行为为 SUPPORTS / NOT_SUPPORTED / NEVER未开启事务管理EnableTransactionManagement异常被捕获未抛出默认只回滚 RuntimeExceptiontry{// 业务代码}catch(Exceptione){// 吃了异常 → 事务不回滚}解决手动TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();多数据源未正确配置事务管理器五、面试/生产最常问的 5 个问题建议背熟REQUIRED 和 REQUIRES_NEW 的区别什么场景用 REQUIRES_NEWNESTED 和 REQUIRES_NEW 的区别保存点 vs 独立事务Spring 事务如何实现AOP 动态代理 TransactionInterceptor事务失效的常见原因有哪些同一个类中Transactional 方法调用另一个 Transactional 方法事务如何传播六、一句话总结Spring 事务的核心就是用 AOP 在方法前后插入 begin/commit/rollback 逻辑而传播行为决定了“当方法嵌套调用时事务应该如何接力或独立”。生产口诀默认 REQUIRED日志/通知用 REQUIRES_NEW保存点用 NESTED查询用 SUPPORTS。如果你现在能说出 7 种传播行为的含义和典型场景写出 3 种事务失效的代码示例解释为什么内部调用 this.method() 会导致事务失效那这篇内容你就已经掌握了 Spring 事务的 80% 精髓。想继续深入哪一块比如多数据源分布式事务Seata / XA声明式事务源码TransactionInterceptor编程式事务TransactionTemplateTransactional 所有属性详解rollbackFor、isolation、timeout 等随时告诉我我继续展开