백엔드/Spring

@Transacntional 의 옵션들

YoungBLUE 개발일지 2025. 4. 1. 00:31

들어가며...

Spring Framework를 이용해서 개발을 하다보면 사용하게 되는 @Transactional 어노테이션을 보다가 문득 내가 사용해본 옵션 말고

어떠한 옵션들이 또 있을까? 궁금해져서 라이브러리 내부를 따라가보았다.

내부에 있는 옵션에 대한 설명들을 보면서 어떤 옵션들을 제공하는지 알아보자.

 

package org.springframework.transaction.annotation;


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
	/**
	 * The transaction propagation type.
	 * <p>Defaults to {@link Propagation#REQUIRED}.
	 * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
	 */
	Propagation propagation() default Propagation.REQUIRED;
...

 

트랜잭션의 주요 특성 (ACID)

트랜잭션에는 ACID라고 하는 4가지 특성이 있는데 이는 다음과 같다.

  • Atomicity (원자성): 트랜잭션 내의 모든 작업은 하나의 작업처럼 처리되며, 만약 트랜잭션 중 하나라도 실패하면 전체 트랜잭션이 롤백(rollback)
  • Consistency (일관성): 트랜잭션이 시작되기 전과 종료 후, 데이터베이스는 항상 일관된 상태를 유지해야한다.
  • Isolation (격리성): 트랜잭션이 다른 트랜잭션에 영향을 미치지 않도록 격리한다. 격리 수준에 따라 다른 트랜잭션의 작업이 현재 트랜잭션에 미치는 영향을 조정할 수 있다.
  • Durability (지속성): 트랜잭션이 완료되면 그 결과는 영구적으로 저장된다. 즉, 시스템 오류가 발생하더라도 커밋된 트랜잭션의 결과는 사라지지 않는다.

위의 특성들을 상황에 따라 어떻게 처리할 것인가에 대해 다음과 같은 옵션들을 제공한다.

 

제공되는 옵션들

@Transactional 에너는 다음과 같은 옵션들을 제공한다.

- propagation

- isolation

- rollbackFor

- noRollbackFor

- readOnly

- timeout

- value

 

이중에서 실제로 현업에서 사용해본 옵션은 readOnly 말고는 딱히 사용 해본적은 없다.

그러나 설명들을 보면서 나중에 기회가 된다면 단순하게 풀어낼 수 없는 로직적인 내용들을 풀어내거나 때론 예상하지 못한 이유로 쓸일이 있을수도 있을 것 같다.

 

propagation

현재 진행중인 트랜잭션 (부모 트랜잭션) 이 존재할 때 새로운 트랜잭션 메소드를 호출하는 경우 어떻게 전파될지를 결정하는 옵션으로 기본 값 REQUIRED

  • REQUIRED (기본값)
    기본 값으로 기존 트랜잭션(부모)이 있으면 참여하고, 없으면 새 트랜잭션을 생성
  • REQUIRES_NEW
    기존 트랜잭션(부모)이 있어도 무조건 새로운 트랜잭션을 생성 (기존 트랜잭션은 잠시 보류됨)
  • SUPPORTS
    기존 트랜잭션이 있으면 참여하고, 없으면 트랜잭션 없이 실행 (non-transactional)
  • MANDATORY
    반드시 기존 트랜잭션이 있어야 하며, 없으면 예외 발생 (TransactionRequiredException)
  • NEVER
    기존 트랜잭션이 있으면 예외 발생 (트랜잭션 없이 실행 - non-transactional)
  • NOT_SUPPORTED
    non-transactional(트랜잭션 없이)으로 시작하며 기존 트랜잭션(부모)이 있으면 보류
  • NESTED
    기존 트랜잭션이 있으면 별개의 중첩된 트랜잭션을 생성하여 실행
    부모 트랜잭션의 커밋과 롤백에는 영향을 받지만 자신의 커밋과 롤백은 부모 트랜잭션에게 영향을 주지 않음
    부모 트랜잭션이 없는 경우 새로운 트랜잭션을 만듦

 

 

isolation

트랜잭션이 다른 트랜잭션과 어떻게 격리될지를 결정하는 옵션으로, 기본값 DEFAULT

  • DEFAULT (기본값)
    데이터베이스의 기본 격리 수준을 따른다.
  • READ_UNCOMMITTED
    다른 트랜잭션에서 commit되지 않은 데이터도 읽을 수 있다. (Dirty Read 가능)
  • READ_COMMITTED
    다른 트랜잭션에서 commit된 데이터만 읽을 수 있다. (Dirty Read 방지)
    A 트랜잭션이 데이터를 변경해도 커밋하기 전이라면 B 트랜잭션은 변경되지 전의 데이터를 조회한다.
  • REPEATABLE_READ
    같은 트랜잭션 내에서 동일한 데이터를 여러 번 읽어도 결과가 변하지 않는다. (Phantom Read 가능)
    다른 트랜잭션에서 수행한 작업에 의해 안보였던 데이터가 보이는 현상이 발생할 수 있다.
    격리 수준은 조회한 데이터에 대해서만 Shared Lock이 걸리기 때문에 다른 트랜잭션이 새로운 데이터를 추가할 수 있다.
  • SERIALIZABLE
    가장 엄격한 격리 수준으로, 트랜잭션 간 충돌을 방지하기 위해 데이터에 대한 순차적 접근을 보장한다. (성능 저하 가능)
    가장 안전하지만 성능 저하가 발생하기 때문에 극도의 안정성을 필요로 하지 않으면 자주 사용되지는 않는다.

 

 

rollbackFor

특정 예외가 발생하면 롤백하도록 설정하는 옵션

@Transactional(rollbackFor = RuntimeException.class)

 

- 사용할 때 @Transactional(rollbackFor = RuntimeException.class) 처럼 특정 Exception Type 발생시 커밋하지 않고 롤백 되도록 설정할 수 있다.

- 기본 값으로 RuntimeException과 Error 가 포함되어 있다. 중요한 점은 다른 Exception을 추가해도 RuntimeException과 Error에 대해 동작한다.

 

 

noRollbackFor

특정 예외가 발생해도 롤백하지 않도록 설정하는 옵션

@Transactional(noRollbackFor = {YoungBlueException.class})

예를 들면 사용자가 직접 정의한 YoungBlue라는 Exception이 있다고 할 때, 해당 Exception이 발생하면 롤백하지 않는다.

 

 

 

readOnly

트랜잭션을 읽기 전용으로 설정하는 옵션

@Transactional(readOnly = true)

- 기본값 false 이고, true로 설정하는 경우 트랜잭션을 읽기 전용으로 변경한다.

- JPA에서 Dirty Checking을 무시하는 상태가 되며, Entity의 상태 변경에 따른 update를 무시하게 된다. (조회용 메소드에 사용)

- 이에 따라 성능이 향상될 수 있다.

 

 

 

timeout

트랜잭션이 수행될 최대 시간을 설정하는 옵션

@Transactional(timeout = 10)

- 기본값은 -1로 이 경우 timeout을 설정하지 않는 것과 같다.

- 지정한 시간 내에 해당 메소드 수행이 완료되지 않을 경우 JpaSystemException을 발생 시킨다.

 

 

 

value

Spring의 여러 트랜잭션 관리자가 있을 경우 특정 트랜잭션 관리자를 지정할 때 사용

@Transactional(value = "transactionManagerName")

 

 

 

 

 

정리

Option Name Description Default
propagation 트랜잭션 전파 방식 REQUIRED
isolation 트랜잭션 격리 수준 DEFAULT
rollbackFor 롤백할 예외 지정 없음
noRollbackFor 롤백하지 않을 예외 지정 없음
readOnly 읽기 전용 트랜잭션 false
timeout 트랜잭션 최대 실행 시간 (초) -1 (무제한)
value 특정 트랜잭션 매니저 지정 없음

 

반응형