개발/spring

[jpa] 커스텀 Transactional 만들기

방푸린 2024. 11. 22. 14:36
반응형

환경: springboot3

 

@Transactional에서 속성을 명시하지 않으면 Spring의 기본값이 적용된다. 알고 써야 한다는!!

1. transactionManager의 기본값

@EnableJpaRepositories로 각 데이터베이스마다 별도의 리포지토리를 설정했더라도, @Transactional을 명시적으로 특정 데이터베이스와 연결하지 않으면 기본 설정된 데이터베이스가 사용된다..! 즉, @Primary로 설정된 빈이 사용됨. 멀티 데이터베이스를 쓰는 프로젝트에서 아무 생각 없이 사용하는 경우 의미 없는 트랜젝션이 설정될 수 있어 조심해야 한다.

2. timeout의 기본값

  • 기본값: -1 (무제한)
  • 트랜잭션이 실행되는 데 시간이 얼마나 걸리든 제한을 두지 않음
  • 데이터베이스에 설정된 타임아웃 값이 있을 경우, 그 값이 적용될 수 있음
  • 명시적으로 설정할 경우, 초 단위로 지정

3. rollbackFor의 기본값

  • 기본값: RuntimeException 및 Error
  • 기본적으로 트랜잭션은 RuntimeException(unchecked exception)이나 Error가 발생했을 때 롤백됨
  • CheckedException(예: SQLException)은 기본적으로 롤백 대상이 아님!!
  • rollbackFor = Throwable.class로 설정하면 모든 예외(Checked와 Unchecked 포함)가 발생 시 트랜잭션이 롤백

4. readOnly

  • 기본값: false
  • 읽기 전용 트랜잭션으로 설정되지 않음
  • 데이터 변경 작업이 가능하며, 최적화를 위해 읽기 전용 작업에서는 readOnly = true를 설정하기

5. propagation

  • 기본값: Propagation.REQUIRED
  • 기존 트랜잭션이 있으면 해당 트랜잭션을 사용하고, 없으면 새로운 트랜잭션을 생성함

6. isolation

  • 기본값: Isolation.DEFAULT
  • 데이터베이스의 기본 격리 수준이 적용됨

커스텀 @Transactional 만들기

매번 트랜젝션 설정을 달아야 하는 게 번거로워서 전용 어노테이션을 만든다.

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional(transactionManager = TransactionConstants.TRANSACTION_MANAGER, timeout = 10, rollbackFor = Throwable.class)
public @interface WriteTransactional {

}

1. @Target

@Target은 애노테이션이 적용될 수 있는 대상(타깃)을 지정

  • ElementType.METHOD: 메서드에 적용 가능
  • ElementType.TYPE: 클래스, 인터페이스, 열거형(enum)에 적용 가능
  • ElementType.FIELD: 필드(멤버 변수)에 적용 가능
  • ElementType.PARAMETER: 메서드 매개변수에 적용 가능
  • ElementType.CONSTRUCTOR: 생성자에 적용 가능
  • ElementType.LOCAL_VARIABLE: 지역 변수에 적용 가능
  • ElementType.ANNOTATION_TYPE: 다른 애노테이션에 적용 가능
  • ElementType.PACKAGE: 패키지에 적용 가능
  • ElementType.TYPE_PARAMETER (Java 8 이상): 제네릭 타입 매개변수에 적용 가능.
  • ElementType.TYPE_USE (Java 8 이상): 모든 타입 선언에 적용 가능

2. @Retention

@Retention은 애노테이션이 얼마나 오래 유지되는지 지정

  • RetentionPolicy.SOURCE:
    • 소스 코드에서만 유지되고, 컴파일 시 제거
    • 코드 문서화나 컴파일러 경고용으로 사용.
    • 예: @Override
  • RetentionPolicy.CLASS:
    • 컴파일된 .class 파일에 포함되지만, 런타임에는 JVM에 의해 로드되지 않음
    • 기본값(Default).
  • RetentionPolicy.RUNTIME:
    • 런타임에도 JVM에 의해 유지
    • 리플렉션(Reflection)으로 접근 가능
    • 예: @Autowired, @RequestMapping.
728x90
반응형