트랜잭션 - 옵션

박찬우·2024년 2월 8일

스프링 DB

목록 보기
42/53

옵션

public @interface Transactional {
  String value() default ""; 
  String transactionManager() default "";
  Class<? extends Throwable>[] rollbackFor() default {}; 
  Class<? extends Throwable>[] noRollbackFor() default {};
  Propagation propagation() default Propagation.REQUIRED; 
  Isolation isolation() default Isolation.DEFAULT; 
  int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; 
  boolean readOnly() default false;  
  String[] label() default {};
}
  • value, transactionManager
    • 트랜잭션을 사용하려면 먼저 스프링 빈에 등록된 어떤 트랜잭션 매니저를 사용할지 알아야 한다. 생각해보면 코드로 직 접 트랜잭션을 사용할 때 분명 트랜잭션 매니저를 주입 받아서 사용했다. @Transactional 에서도 트랜잭션 프록시 가 사용할 트랜잭션 매니저를 지정해주어야 한다. 사용할 트랜잭션 매니저를 지정할 때는 value , transactionManager 둘 중 하나에 트랜잭션 매니저의 스프링 빈 의 이름을 적어주면 된다. 이 값을 생략하면 기본으로 등록된 트랜잭션 매니저를 사용하기 때문에 대부분 생략한다. 그런데 사용하는 트랜잭션 매 니저가 둘 이상이라면 다음과 같이 트랜잭션 매니저의 이름을 지정해서 구분하면 된다
public class TxService {
    @Transactional("memberTxManager")    
    public void member() {...}
    
    @Transactional("orderTxManager")    
    public void order() {...} 
}
  • rollbackFor
    • 예외 발생시 스프링 트랜잭션의 기본 정책은 다음과 같다.
      • 언체크 예외인 RuntimeException , Error 와 그 하위 예외가 발생하면 롤백한다.
      • 체크 예외인 Exception 과 그 하위 예외들은 커밋한다.
    • 이 옵션을 사용하면 기본 정책에 추가로 어떤 예외가 발생할 때 롤백할 지 지정할 수 있다.
    • rollbackForClassName 도 있는데, rollbackFor 는 예외 클래스를 직접 지정하고, rollbackForClassName 는 예외 이름을 문자로 넣으면 된다.
@Transactional(rollbackFor = Exception.class)
  • noRollbackFor
    • rollbackFor 와 반대이다. 기본 정책에 추가로 어떤 예외가 발생했을 때 롤백하면 안되는지 지정할 수 있다. 예외 이름을 문자로 넣을 수 있는 noRollbackForClassName 도 있다.
  • propagation
    • 트랜잭션 전파에 대한 옵션이다
  • isolation
    • 트랜잭션 격리 수준을 지정할 수 있다. 기본 값은 데이터베이스에서 설정한 트랜잭션 격리 수준을 사용하는 DEFAULT 이다. 대부분 데이터베이스에서 설정한 기준을 따른다. 애플리케이션 개발자가 트랜잭션 격리 수준을 직접 지정하는 경우는 드물다.
    • DEFAULT : 데이터베이스에서 설정한 격리 수준을 따른다.
    • READ_UNCOMMITTED : 커밋되지 않은 읽기
    • READ_COMMITTED : 커밋된 읽기
    • REPEATABLE_READ : 반복 가능한 읽기
    • SERIALIZABLE : 직렬화 가능
  • timeout
    • 트랜잭션 수행 시간에 대한 타임아웃을 초 단위로 지정한다. 기본 값은 트랜잭션 시스템의 타임아웃을 사용한다. 운영 환경에 따라 동작하는 경우도 있고 그렇지 않은 경우도 있기 때문에 꼭 확인하고 사용해야 한다. timeoutString 도 있는데, 숫자 대신 문자 값으로 지정할 수 있다.
  • label
    • 트랜잭션 애노테이션에 있는 값을 직접 읽어서 어떤 동작을 하고 싶을 때 사용할 수 있다. 일반적으로 사용하지 않는다.
  • readOnly
    • 트랜잭션은 기본적으로 읽기 쓰기가 모두 가능한 트랜잭션이 생성된다. readOnly=true 옵션을 사용하면 읽기 전용 트랜잭션이 생성된다. 이 경우 등록, 수정, 삭제가 안되고 읽기 기능만 작동한다. (드라이버나 데이터베이스에 따라 정상 동작하지 않는 경우도 있다.) 그리고 readOnly 옵션을 사용하면 읽 기에서 다양한 성능 최적화가 발생할 수 있다.
    • readOnly 옵션은 크게 3곳에서 적용된다.
      • 프레임워크
        • JdbcTemplate은 읽기 전용 트랜잭션 안에서 변경 기능을 실행하면 예외를 던진다. JPA(하이버네이트)는 읽기 전용 트랜잭션의 경우 커밋 시점에 플러시를 호출하지 않는다. 읽기 전용이니 변 경에 사용되는 플러시를 호출할 필요가 없다. 추가로 변경이 필요 없으니 변경 감지를 위한 스냅샷 객체도 생성하지 않는다. 이렇게 JPA에서는 다양한 최적화가 발생한다.
      • JDBC 드라이버
        • 참고로 여기서 설명하는 내용들은 DB와 드라이버 버전에 따라서 다르게 동작하기 때문에 사전에 확인이 필 요하다. 읽기 전용 트랜잭션에서 변경 쿼리가 발생하면 예외를 던진다. 읽기, 쓰기(마스터, 슬레이브) 데이터베이스를 구분해서 요청한다. 읽기 전용 트랜잭션의 경우 읽기(슬레이 브) 데이터베이스의 커넥션을 획득해서 사용한다. 예) https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-source-replicareplication-connection.html
      • 데이터베이스
        • 데이터베이스에 따라 읽기 전용 트랜잭션의 경우 읽기만 하면 되므로, 내부에서 성능 최적화가 발생한다.
profile
진짜 개발자가 되어보자

0개의 댓글