Transactional

꽃봉우리·2024년 7월 11일

Transactional이란?

@Transactional은 스프링 프레임워크에서 제공하는 어노테이션으로, 주로 데이터베이스 트랜잭션 관리를 위해 사용된다. 이 어노테이션을 사용하면 메서드나 클래스가 트랜잭션 내에서 실행되도록 설정할 수 있다. 트랜잭션은 일련의 데이터베이스 작업들을 하나의 단위로 묶어서, 전체 작업이 성공하면 커밋(commit)하고, 중간에 실패하면 롤백(rollback)하여 데이터의 일관성과 무결성을 보장한다.

주요 기능

  • 트랜잭션 시작과 종료: @Transactional이 적용된 메서드가 호출되면, 스프링은 트랜잭션을 시작하고, 메서드가 정상적으로 완료되면 트랜잭션을 커밋한다. 만약 예외가 발생하면 트랜잭션을 롤백한다.

  • 예외 처리: 기본적으로 RuntimeException 및 그 하위 클래스가 발생할 경우 트랜잭션이 롤백된다. 그러나 특정 예외에 대해 롤백 또는 커밋 동작을 커스터마이징할 수 있다.

  • 전파(Propagation): 트랜잭션이 이미 진행 중일 때 새로운 트랜잭션을 시작할지, 기존 트랜잭션에 참여할지, 아니면 별도의 트랜잭션으로 처리할지 등을 설정할 수 있다.

  • 격리 수준(Isolation Level): 데이터 일관성을 유지하기 위해 트랜잭션 격리 수준을 설정할 수 있다. 이는 트랜잭션이 다른 트랜잭션과 어떤 방식으로 상호작용할지 정의한다.

사용 예제

  • 클래스 수준에서 사용

클래스에 @Transactional을 적용하면 클래스의 모든 public 메서드에 트랜잭션이 적용된다.

@Service
@Transactional
public class UserService {
    
    public void createUser(User user) {
        // 트랜잭션 시작
        // 사용자 생성 로직
        // 트랜잭션 커밋 또는 롤백
    }
    
    public User getUser(Long id) {
        // 트랜잭션 시작
        // 사용자 조회 로직
        // 트랜잭션 커밋 또는 롤백
    }
}
  • 메서드 수준에서 사용

특정 메서드에만 트랜잭션을 적용하고자 할 때는 메서드에 @Transactional을 직접 지정할 수 있다.

@Service
public class OrderService {
    
    @Transactional
    public void placeOrder(Order order) {
        // 트랜잭션 시작
        // 주문 처리 로직
        // 트랜잭션 커밋 또는 롤백
    }
    
    public Order getOrder(Long id) {
        // 이 메서드에는 트랜잭션이 적용되지 않음
        // 주문 조회 로직
    }
}

트랜잭션 전파와 격리 수준 설정

트랜잭션 전파 및 격리 수준을 설정하여 더욱 정밀하게 트랜잭션 동작을 제어할 수 있다.

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)
public void processPayment(Payment payment) {
    // 트랜잭션 시작
    // 결제 처리 로직
    // 트랜잭션 커밋 또는 롤백
}

언제 사용하는가?

  • 데이터 무결성 보장: 데이터베이스 작업을 수행할 때, 일관성 있는 상태를 유지해야 할 경우에 사용한다. 예를 들어, 은행 계좌 이체에서 출금과 입금 작업이 모두 성공해야 하는 경우.

  • 에러 처리: 작업 중 오류가 발생했을 때, 이전 작업들을 원상태로 돌려야 할 때 사용한다. 예를 들어, 여러 테이블에 데이터를 삽입하는 작업에서 중간에 오류가 발생했을 때, 이미 삽입된 데이터를 모두 롤백해야 하는 경우.

  • 복잡한 비즈니스 로직: 여러 데이터베이스 연산이 하나의 논리적 작업 단위로 묶여야 하는 경우에 사용한다.

0개의 댓글