@Transactional 알아보기

2025. 6. 19. 11:56스프링

@Transactional에 대해서 알아보기 전에 우선 트랜잭션이 무엇인지에 대해서 알아야 합니다.

트랜잭션에 대한 내용은 여기에 정리해 두었습니다.


 

@Transactional의 기본 동작

스프링에서 @Transactional 어노테이션을 메서드나 클래스에 붙이면, 해당 범위 내의 DB 작업을 하나의 트랜잭션으로 묶어 처리합니다.

@Service 
public class UserService { 
    @Transactional
    public void createUser(User user) { 
    	userRepository.save(user); 
        emailService.sendWelcomeEmail(user); 
    }
}

 

위 코드에서 문제가 발생해 예외가 던져지면, save() 작업은 롤백(rollback)됩니다.

 

@Service
@Transactional
public class UserService { 
    public void createUser(User user) { 
        ...
        // 트랜잭션 적용됨
    }
    
    @Transactional(readOnly = true)
    public User getUser(String id) {
        ...
        // readOnly 트랜잭션 적용됨
    }
}

 

클래스 레벨에서 @Transactional을 붙이면 해당 클래스 내 모든 public 메서드에 대해서 트랜잭션이 적용됩니다.

여기서 해당 클래스 내의 메서드에 @Transactional을 적용하면 메서드 레벨이 우선으로 적용됩니다.

즉, 클래스 레벨에 적용해서 모든 public 메서드에 트랜잭션을 적용하고 필요한 메서드만 다른 설정으로 덮어쓸 수 있습니다.

 


 

주요 속성 정리

@Transactional의 주요 속성은 아래와 같습니다.

propagation 트랜잭션 전파 방식 (기본값: REQUIRED)
isolation 트랜잭션 격리 수준 (기본값: DB 기본 수준)
rollbackFor 어떤 예외가 발생했을 때 롤백할지 지정 (Exception.class 등)
noRollbackFor 롤백하지 않을 예외 지정 (CustomException.class 등)
readOnly 읽기 전용 트랜잭션 여부 설정 (성능 최적화 가능)
timeout 트랜잭션 최대 실행 시간(초 단위)
@Transactional(propagation = Propagation.REQUIRES_NEW, 
               isolation = Isolation.SERIALIZABLE,
               rollbackFor = Exception.class,
               readOnly = false,
               timeout = 10)

 

propagation

더보기

propagation은 트랜잭션 전파 방식을 말하며, 현재 실행 중인 트랜잭션이 있을 경우 어떻게 처리할 것 인지를 정의합니다.

 

  1. REQUIRED : 기본값으로 기존 트랜잭션이 있으면 참여, 없으면 생성
  2. REQUIRED_NEW : 항상 새 트랜잭션을 생성하고, 기존 트랜잭션은 일시 중단
  3. NESTED : 기존 트랜잭션 내부에 중첩 트랜잭션 생성 (주로 같은 트랜잭션 내에서 일부만 롤백하고 싶을 때 사용)
  4. SUPPORTS : 기존 트랜잭션이 있으면 참여, 없으면 트랜잭션 없이 실행
  5. NOT_SUPPORTED : 기존 트랜잭션 있으면 일시 중단 후 트랜잭션 없이 실행
  6. MANDATORY : 반드시 트랜잭션 내에서 실행, 없으면 예외 발생
  7. NEVER : 트랜잭션이 있으면 예외를 발생

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html

isolation

더보기

isolation은 트랜잭션의 격리 수준을 말합니다.

동시에 여러 트랜잭션이 같은 데이터에 접근할 때 어떤 것이 허용/차단될지를 정의합니다.

 

해당 내용은 트랜잭션에 대한 설명글에서 자세히 볼 수 있습니다.

 


 

주의할 점

  • 프록시 기반 AOP이기 때문에 같은 클래스 내부에서 메서드 호출 시 트랜잭션이 적용되지 않을 수 있습니다.
  • 기본적으로 RuntimeException 및 그 하위 예외만 롤백됩니다. 체크 예외는 rollbackFor로 명시해 줘야 롤백됩니다.
  • 트랜잭션이 필요하지 않은 작업에까지 트랜잭션을 걸어둔다면 해당 트랜잭션이 DB 커넥션을 점유하고 있기 때문에 리소스 낭비가 될 수 있습니다.