이로

Spring boot Transaction 전파 및 적용 범위 본문

컴퓨터/Spring

Spring boot Transaction 전파 및 적용 범위

利路 2024. 11. 27. 22:40
반응형

Transaction 이란?

트랜잭션(Transaction)은 데이터베이스의 상태를 변환하는 하나 이상의 작업들을 묶은 것으로, 일련의 작업들이 모두 성공하거나 모두 실패해야 하는 원자적(atomic) 단위를 의미합니다. 이를 통해 데이터의 일관성(consistency), 격리성(isolation), 지속성(durability)을 보장합니다. 트랜잭션의 4가지 주요 특성은 ACID라고 불리며, 각각 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), **지속성(Durability)**을 가리킵니다.

 


 

트랜잭션의 사용처

트랜잭션은 데이터 일관성을 보장해야 하는 모든 상황에서 사용됩니다.

예를 들어:

  • 주문 처리 시스템: 재고 감소, 결제, 주문 기록 등이 모두 성공하거나 모두 실패해야 함.
  • 데이터 동기화 작업: 여러 테이블의 상태를 일관되게 유지하기 위해 트랜잭션이 필요함.

 


Spring boot Transactional 옵션

@Transactional(
    propagation = Propagation.REQUIRED,  // 전파 옵션
    isolation = Isolation.DEFAULT,       // 격리 수준
    timeout = -1,                        // 타임아웃
    readOnly = false,                    // 읽기 전용
    rollbackFor = Exception.class,       // 롤백 대상
    noRollbackFor = IOException.class    // 롤백 제외
)

 

스프링 부트에서 제공하는 @Transactional 애노테이션은 다양한 옵션을 통해 트랜잭션 동작을 제어합니다.

  • Propagation: 트랜잭션의 전파 수준을 결정하며, 트랜잭션 간의 관계를 정의합니다.
    • REQUIRED: 기본값으로, 이미 트랜잭션이 존재하면 그 트랜잭션을 사용하고, 없으면 새로운 트랜잭션을 시작합니다.
    • REQUIRES_NEW: 항상 새로운 트랜잭션을 생성하고, 기존 트랜잭션은 일시 중단합니다.
    • NESTED: 기존 트랜잭션 내에서 중첩 트랜잭션을 시작합니다.
  • Isolation: 트랜잭션의 격리 수준을 정의하며, 동시성 문제를 방지합니다.
    • READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE 등.
  • Timeout: 트랜잭션이 지정된 시간 내에 완료되지 않으면 자동으로 롤백합니다.
  • ReadOnly: 트랜잭션이 읽기 전용임을 명시하여 최적화할 수 있습니다.
  • RollbackFor: 특정 예외가 발생했을 때 트랜잭션을 롤백하도록 지정합니다.

Spring boot Transactional 사용 시 주의사항

 

  • Lazy Loading: 트랜잭션 범위를 벗어나면 지연 로딩이 실패할 수 있습니다.
  • Propagation 설정 주의: 트랜잭션 전파 수준을 잘못 설정하면 의도하지 않은 동작이 발생할 수 있습니다.
  • Checked 예외와 롤백: 기본적으로 @Transactional은 언체크(Runtime) 예외에 대해서만 롤백하고, 체크 예외에 대해서는 롤백하지 않습니다. 특정 체크 예외에 대해서도 롤백이 필요하다면 rollbackFor 속성을 설정해야 합니다.
  • DB 락: 트랜잭션이 오래 지속되면 데이터베이스 락을 유발하여 성능 저하 또는 Deadlock의 위험이 있습니다.

private 메소드에는 적용 불가

  • Spring의 트랜잭션은 프록시 방식으로 동작하기 때문에 이런 제약사항이 있습니다.
@Service
public class UserService {
    @Transactional
    public void updateUser() {
        privateMethod(); // 트랜잭션 적용 안됨
        this.privateMethod(); // 트랜잭션 적용 안됨
    }

    private void privateMethod() {
        // private 메서드에 @Transactional을 붙여도 동작 안함
    }
}

 

  • 스프링은 해당 클래스를 상속한 프록시 객체를 생성하여 트랜잭션을 처리
  • private 메서드는 상속이 불가능하므로 프록시가 생성되지 않음
  • 내부 호출(this)의 경우 프록시를 거치지 않고 직접 호출되어 트랜잭션 적용 불가

private 메소드에 transaction 적용하고 싶을 경우엔?

@Service
public class UserService {
    @Autowired
    private UserService self; // 프록시 객체 주입

    @Transactional
    public void updateUser() {
        self.privateMethod(); // 프록시를 통한 호출로 트랜잭션 적용
    }
}

 

 


중첩된 트랜잭션의 에러 전파 및 롤백 범위

여러 개의 트랜잭션이 중첩되었을 때의 에러 전파 및 롤백 범위는 Propagation 설정에 따라 다릅니다.

  • REQUIRED: 내부 트랜잭션에서 에러가 발생하면 외부 트랜잭션까지 영향을 받아 전체 롤백됩니다.
  • REQUIRES_NEW: 내부 트랜잭션에서 에러가 발생해도 외부 트랜잭션에는 영향을 미치지 않습니다. 내부 트랜잭션만 롤백됩니다.
  • NESTED: 내부 트랜잭션에서 에러가 발생하면 해당 내부 트랜잭션만 롤백되며, 외부 트랜잭션에는 영향을 미치지 않지만, 외부 트랜잭션에서 롤백이 발생하면 내부 트랜잭션도 함께 롤백됩니다.
반응형

'컴퓨터 > Spring' 카테고리의 다른 글

querydsl 의존성에 의한 JSP 컴파일 에러  (0) 2021.05.12
Spring boot url root path  (0) 2020.08.15
DB connection pool 이란?  (0) 2019.10.23
Spring MVC Board 기본 구성(Ver.마이바티스)  (0) 2019.08.13
스프링  (0) 2019.07.24
Comments