requires_new 通过 transactionsynchronizationmanager 暂存当前事务资源(如 connection)并新建独立事务,执行后恢复原事务;必须经 spring 代理调用才生效。

在 Java 的 Spring 事务管理中,REQUIRES_NEW 传播行为会**挂起当前事务(如有),并启动一个全新的、独立的事务**。它不依赖外层事务的状态,即使外层事务回滚,REQUIRES_NEW 方法中的操作仍可正常提交。
REQUIRES_NEW 是如何挂起当前事务的?
Spring 并非真正“暂停”事务,而是通过 事务同步管理器(TransactionSynchronizationManager) 将当前事务资源(如数据库连接、事务状态)绑定到当前线程的 ThreadLocal 中,并在进入 REQUIRES_NEW 方法前将其暂存(suspend),同时创建新的事务资源。方法执行完后,再将原事务资源恢复(resume)。
- 挂起时:Spring 把当前事务的 Connection、isActive 状态等保存为一个
SuspendedResources对象 - 新建事务:获取新 Connection,开启新事务,独立执行 SQL
- 恢复时:把挂起的资源重新绑定回当前线程,继续原事务流程
必须用代理方式调用才能生效
REQUIRES_NEW 依赖 Spring AOP 代理拦截,因此不能在同一个类内直接调用,否则绕过代理,事务失效。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- ✅ 正确:通过注入的 service 接口调用(如
otherService.doWithNewTx()) - ❌ 错误:this.doWithNewTx() 或普通方法内调用 —— 不走代理,无事务控制
- ⚠️ 补救(不推荐):使用
AopContext.currentProxy()强制走代理,但破坏封装且需开启 expose-proxy
典型应用场景与注意事项
适用于需要强隔离性、失败不影响主流程的场景,比如日志记录、异步通知、补偿操作等。
- 日志写入:主业务失败回滚,但审计日志仍要落库 → 用
REQUIRES_NEW - 发送消息:确保消息记录成功,哪怕主事务 rollback → 单独事务保障
- 注意嵌套开销:每次
REQUIRES_NEW都涉及连接获取/释放、事务 begin/commit,频繁使用影响性能 - 注意异常处理:若新事务内抛出未捕获异常,默认触发 rollback;如需忽略,需显式 try-catch + 不抛出
代码示例(关键部分)
```java
@Service
public class OrderService {
@Autowired
private LogService logService;
@Transactional
public void createOrder(Order order) {
// 主事务:创建订单
orderMapper.insert(order);
// 调用独立事务方法(必须通过代理)
logService.recordSuccessLog(order.getId()); // ← 这里开启新事务
// 若此处抛异常,主事务回滚,但日志已提交
}
}
@Service
public class LogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void recordSuccessLog(Long orderId) {
logMapper.insert(new Log("ORDER_CREATED", orderId));
}
}
```
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










