Spring 트랜잭션 전파 동작: Spring 6 / Boot 3 실전 경계
1. 전파 동작
- REQUIRED: 트랜잭션이 있으면 참여하고, 없으면 새로 생성합니다.
- REQUIRES_NEW: 외부 트랜잭션을 중단하고 독립적인 트랜잭션을 생성하므로 커넥션을 추가로 사용합니다.
- SUPPORTS: 트랜잭션이 있으면 참여하고, 없어도 트랜잭션 없이 실행할 수 있습니다.
- NOT_SUPPORTED: 트랜잭션을 중단하고 비 트랜잭션 방식으로 실행합니다.
- MANDATORY: 기존 트랜잭션이 반드시 있어야 합니다.
- NEVER: 트랜잭션이 있으면 실패합니다.
- NESTED: 세이브포인트를 지원하는 트랜잭션에서 중첩 경계를 설정합니다.
2. 예제
JAVA
@Service
public class OrderService {
@Transactional(rollbackFor = Exception.class)
public void create(Order order) {
repository.insert(order);
auditService.record(order.id());
}
}
@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void record(long id) {
// 独立提交审计事务
}
}
3. 트랜잭션이 적용되지 않는 경우
선언적 트랜잭션은 프록시에 의존하므로 this.innerMethod()는 프록시를 우회할 수 있습니다. 그 밖의 원인으로 Bean을 new로 생성했거나, 예외를 catch했거나, checked exception에 rollbackFor를 설정하지 않았거나, 다른 스레드에서 호출했거나, 데이터베이스가 트랜잭션을 지원하지 않거나, 잘못된 트랜잭션 관리자를 사용한 경우가 있습니다. 가능한 한 Bean을 분리하여 호출이 프록시를 거치도록 하세요.
4. 시스템 경계
NESTED는 일반적으로 동일한 물리적 트랜잭션과 세이브포인트에 의존하며, REQUIRES_NEW는 독립적인 물리적 트랜잭션을 사용합니다. Spring의 로컬 트랜잭션은 스레드, MQ, HTTP 또는 RPC를 자동으로 가로질러 전파되지 않습니다. 서비스 간 트랜잭션에는 신뢰할 수 있는 메시징, 보상 처리, TCC 또는 Seata를 사용하세요.