@Transactional 属性:传播、隔离、回滚

引言

声明式事务把事务边界从代码里移到注解上:@Transactional 标注方法/类,事务由代理在调用边界自动开启、提交或回滚。真正要掌握的是注解上那几个属性——传播行为、隔离级别、回滚规则——它们决定事务“怎么嵌套、怎么隔离、何时回滚”。

核心概念

  • 开启:纯 Spring 需 @EnableTransactionManagement;Spring Boot 引了 spring-boot-starter-jdbc/*-data-jpa 等会自动开启(以官方文档为准)。代理模式(默认)下仅拦截 public 方法与外部调用。
  • 传播行为(Propagation,默认 REQUIRED)
    • REQUIRED:有事务就加入,没有就新建;
    • REQUIRES_NEW:总是挂起外层、新开独立事务;
    • NESTED:在保存点(savepoint)上嵌套,内层可单独回滚到保存点;
    • SUPPORTS/NOT_SUPPORTED/MANDATORY/NEVER:可有可无/挂起外层/必须有否则异常/禁止有事务。
  • 隔离级别(Isolation,默认 DEFAULT=数据库默认)READ_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLE;实际效果以数据库实现为准(如 MySQL InnoDB 默认 REPEATABLE_READ,以官方文档为准)。
  • 回滚规则(默认)RuntimeExceptionError 触发回滚;受检异常默认不回滚。可用 rollbackFor = Exception.class 扩大,noRollbackFor 缩小。
  • 其他属性:readOnly = true 是只读提示(优化/校验用,不等于强制禁止写,具体以提供者实现为准)、timeout(秒,超时自动回滚)、rollbackForClassName/noRollbackForClassName
  • 标注位置:类级别=该类所有 public 方法默认值;方法级别覆盖类级别,越具体越优先。

代码示例

@Service
public class OrderService {
    @Transactional                            // REQUIRED + 默认回滚规则
    public void createOrder(Order order) {
        orderDao.insert(order);
        paymentService.pay(order);            // REQUIRED:加入当前事务
        inventoryService.deduct(order);       // REQUIRES_NEW:独立事务
    }
}

@Service
public class PaymentService {
    @Transactional(propagation = Propagation.REQUIRED)
    public void pay(Order order) { /* 与 createOrder 同事务,一起提交/回滚 */ }
}

@Service
public class InventoryService {
    // 即使外层稍后回滚,扣减也已独立提交(REQUIRES_NEW 的代价)
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void deduct(Order order) { /* 独立事务 */ }

    @Transactional(rollbackFor = Exception.class, readOnly = false)
    public void risky() throws Exception { /* 受检异常也回滚 */ }
}

注意点

  • REQUIRED 嵌套不是“内层独立事务”,内层异常回滚会把整个外层一起带崩;想要局部隔离用 REQUIRES_NEW(各自提交)或 NESTED(保存点)。
  • 受检异常默认不回滚是新人第一坑:忘写 rollbackFor = Exception.class,业务异常被“提交”了。
  • 代理模式下注解加在接口上只在 JDK 代理+外部调用时有效,官方建议直接标注具体类/方法(以官方文档为准)。
  • 隔离级别由数据库实现兜底,DEFAULT 最常见;乱升 SERIALIZABLE 会显著降并发。
  • readOnly 别当约束用;timeout 默认按事务管理器实现,单位秒。

小结

@Transactional 三组关键词:传播(怎么嵌套)、隔离(怎么并发可见)、回滚规则(什么异常算失败)。先背默认值(REQUIRED / DEFAULT / 仅运行时异常回滚),再按业务逐条显式声明,事务行为即可预测。

笔记加载中…