최근에 트랜잭션 적용하다가 문제 현상이 보여서 정리해보려고 한다.
@Service
public class ServiceA {
@Transactional
public void saveMain() {
saveData(); // 메인 저장
serviceB.saveLog(); // 로그 저장
}
}
@Service
public class ServiceB {
@Transactional
public void saveLog() {
throw new RuntimeException("로그 저장 실패");
}
}
@Transactional 기본 전파 옵션이 REQUIRED라서, 이미 트랜잭션이 있으면 그냥 이어서 실행함saveMain() 트랜잭션 안에 saveLog()도 같이 묶인 상태로그는 실패해도 메인 트랜잭션에 영향 없도록 독립 트랜잭션으로 만들면 됨.
@Service
public class ServiceB {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveLog() {
logRepository.save(new LogEntity(...));
}
}
REQUIRES_NEW → 항상 새 트랜잭션 시작, 기존 트랜잭션은 잠시 보류@Service
public class ServiceA {
@Transactional
public void saveMain() {
saveData(); // 주문 저장
try {
serviceB.saveLog(); // 로그 저장
} catch (Exception e) {
// 실패해도 메인 트랜잭션은 유지
System.out.println("로그 실패, 주문 저장은 그대로");
}
}
}
REQUIRED는 기존 트랜잭션에 합류 → 한쪽 실패하면 전체 rollbackREQUIRES_NEW