Spring事务传播行为默认REQUIRED,决定方法如何参与事务;隔离级别默认ISOLATION_DEFAULT,控制读写可见性以避免脏读等。两者通过@Transactional注解配置,底层由RuleBasedTransactionAttribute封装,仅对public方法生效。

Spring 中事务的传播行为和隔离级别,是通过 @Transactional 注解的属性直接配置的,底层由 TransactionAttribute 接口及其默认实现类(如 RuleBasedTransactionAttribute)封装。你不需要手动 new 或构造它,只需在注解中声明即可,Spring 容器会在代理创建时自动解析为对应的 TransactionAttribute 实例。
传播行为 propagation 怎么配
传播行为决定当前方法如何参与事务——是加入已有事务、新建一个、还是不走事务。默认是 REQUIRED,最常用。
- PROPAGATION_REQUIRED:有事务就加入,没事务就新建(默认值)
- PROPAGATION_REQUIRES_NEW:不管有没有,都新建独立事务(旧事务会被挂起)
- PROPAGATION_NESTED:有事务则建嵌套子事务(依赖 JDBC Savepoint),无则等同 REQUIRED
- PROPAGATION_SUPPORTS:有就加入,无就非事务运行
- PROPAGATION_MANDATORY:必须有外部事务,否则抛异常
- PROPAGATION_NOT_SUPPORTED:挂起当前事务,以非事务方式执行
- PROPAGATION_NEVER:绝对不能有事务,有则抛异常
写法示例:
```java@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doSomething() { /* ... */ }
```
隔离级别 isolation 怎么配
隔离级别控制事务间读写可见性,避免脏读、不可重复读、幻读。默认是 ISOLATION_DEFAULT,即交由数据库决定(MySQL 默认 REPEATABLE_READ,PostgreSQL/Oracle 默认 READ_COMMITTED)。
立即学习“Java免费学习笔记(深入)”;
- ISOLATION_READ_COMMITTED:防止脏读,常见于 Oracle 和多数业务场景
- ISOLATION_REPEATABLE_READ:防止脏读 + 不可重复读,MySQL 默认
- ISOLATION_SERIALIZABLE:最严格,串行执行,性能差,一般不用
- ISOLATION_READ_UNCOMMITTED:最低级,允许脏读,基本不用
写法示例:
```java@Transactional(isolation = Isolation.READ_COMMITTED)
public void queryUser() { /* ... */ }
```
组合使用与注意事项
传播和隔离可以同时设置,也支持 rollbackFor、timeout、readOnly 等其他属性:
```java@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
rollbackFor = Exception.class,
timeout = 30,
readOnly = false
)
public void transferMoney(String from, String to, BigDecimal amount) { /* ... */ }
```
注意点:
- 只对 public 方法生效;private / protected / package-private 方法加了也无效
- 同一类内方法互相调用(非代理调用)不会触发事务,需拆到不同 Bean 或用
AopContext.currentProxy() - 异常必须“逃出”被代理方法才会回滚,默认只对 RuntimeException 和 Error 回滚
- REQUIRES_NEW 和 NESTED 在事务嵌套场景下行为差异大,尤其涉及回滚时要特别验证


















