INSIGHTS · Technology
Spring Boot @Transactional 롤백 실패 원인과 REQUIRES_NEW 사용 시 주의사항
BLICT · 2026. 10. 21. · 수정 2026. 10. 21.
@Transactional을 적용했을 때 예외 발생 시 DB 롤백이 되지 않는 이유와 REQUIRES_NEW 사용 시 발생할 수 있는 데이터 정합성 문제를 분석합니다.
@Transactional 롤백 실패의 원인
Spring Boot에서 @Transactional을 사용해도 예외 발생 시 DB가 롤백되지 않는 이유는 여러 가지가 있습니다. 첫째, 롤백이 발생하는 경우는 RuntimeException과 그 하위 클래스에서만 작동합니다. 만약 checked exception이 발생하면, 기본적으로 트랜잭션은 롤백되지 않습니다. 예를 들어, 커스텀 예외로 체크된 예외를 던지면, 해당 트랜잭션은 커밋되고 데이터베이스에 변화가 반영됩니다.
둘째, 트랜잭션의 경계가 어디에 설정되느냐에 따라 롤백 동작이 달라집니다. 내부 메서드에서 @Transactional을 사용한 경우, 해당 메서드가 호출되어도 상위 트랜잭션의 경계 내에서 실행되므로, 예외가 발생하더라도 롤백되지 않을 수 있습니다. 이는 Spring의 AOP 기반 트랜잭션 관리 방식으로 인한 현상입니다.
비동기 실행의 영향
비동기 실행은 트랜잭션 관리에 있어 또 다른 복잡성을 더합니다. @Async 애너테이션을 사용하면 메서드는 비동기적으로 실행되고, 이 경우 트랜잭션 경계가 달라집니다. 비동기 메서드 내부에서 발생한 예외는 호출한 메서드의 트랜잭션에 영향을 미치지 않기 때문에, 롤백이 발생하지 않습니다.
예를 들어, 비동기 메서드에서 DB 작업을 수행하고 예외가 발생하더라도, 호출한 메서드의 트랜잭션은 여전히 커밋될 수 있습니다. 이는 비동기의 특성상 별도의 스레드에서 실행되기 때문입니다. 비동기 메서드에서 트랜잭션을 관리하려면, 해당 메서드에도 @Transactional을 추가해야 합니다.
트랜잭션 전파 속성과 데이터 정합성
Spring의 트랜잭션 전파 속성은 여러 트랜잭션을 어떻게 관리할지를 결정합니다. REQUIRES_NEW는 새로운 트랜잭션을 시작하고, 현재의 트랜잭션이 존재하면 이를 일시 중단합니다. 이 경우, 현재 트랜잭션의 롤백과는 무관하게 새로운 트랜잭션이 커밋됩니다.
이러한 특성으로 인해 REQUIRES_NEW를 잘못 사용하면 데이터 정합성 문제가 발생할 수 있습니다. 예를 들어, 상위 트랜잭션에서 예외가 발생해 롤백이 되었지만, REQUIRES_NEW로 시작된 하위 트랜잭션은 이미 커밋되어 데이터 불일치가 발생할 수 있습니다. 이로 인해 데이터베이스의 상태가 예상치 못한 결과로 이어질 수 있습니다.
예외 처리 및 롤백 관리
예외 처리를 통해 트랜잭션의 롤백을 보다 효과적으로 관리할 수 있습니다. @Transactional을 적용한 메서드에서 발생한 예외를 처리하고, 필요한 경우 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 메서드를 호출하여 롤백을 강제할 수 있습니다.
이 방법은 특히 체크된 예외가 발생하는 경우 유용하게 사용할 수 있습니다. 예를 들어, 특정 비즈니스 로직에서 예외가 발생했을 때, 명시적으로 롤백을 요청하여 데이터의 일관성을 유지할 수 있습니다.
체크리스트
@Transactional사용 시 예외 종류에 따른 롤백 동작을 이해하고 있나요?- 비동기 메서드에서
@Transactional을 올바르게 사용하고 있나요? - 트랜잭션 전파 속성을 적절하게 활용하고 있나요?
- 예외 처리 로직에서 명시적으로 롤백을 설정하고 있나요?
REQUIRES_NEW사용 시 데이터 정합성을 고려하고 있나요?