@Transactional

  • 트랜잭션 2가지 방법

    • 어노테이션 이용

    • AOP

여기선 어노테이션 @Transactional 을 사용하는 방법과 주의할 점에 대해 알아보자.

설정

@Configuration
@EnableTransactionManagement // 스프링 3.1에 등장 어노테이션
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean
     entityManagerFactory(){
      //...
   }

   @Bean
   public PlatformTransactionManager transactionManager(){
      JpaTransactionManager transactionManager
        = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(
        entityManagerFactory().getObject() );
      return transactionManager;
   }
}

Spring Boot 의 경우에는 클래스 패스에 있는 spring-data-* 나 spring-tx 가 트랜잭션 관리 설정 역할을 대신해준다.

@Transactional 어노테이션

  • 설정 가능 옵션

    • Propagation 타입

    • isolation Level 레벨: 동시에 발생된 트랜잭션에 의해 적용된 변경 사항이 서로에게 어떻게 보이는지 설정

      • READ_UNCOMMITED(커밋되지 않은 읽기)

        • 문제점: DIRTY READ

      • READ_COMMITTED(커밋된 읽기

        • 문제점: NON-REPEATABLE READ

        • 설명: 트랜잭션1에서 조회후 트랜잭션1에서 다시 읽었는데 다른 데이터값. 트랜잭션2에서 그 사이 변경해버렸다.

      • REPEATABLE_READ(반복 가능한 읽기)

        • 문제점: PHANTOM READ

        • 설명: 트랜잭션1에서 5개 데이터 나왔는데 다시 조회하니 6개. 트랜잭션2에서 그사이 추가해버렸다.

          위에는 다른 트랜잭션에서 수정시 발생했고 이번에는 추가시 발생.

      • SERIALIZABLE (직렬화가능)

    • Timeout 설정

    • readOnly 플래그

    • Rollback 룰

      • 2가지 방법

        • 어노테이션 방법

          • @Transactional(rollbackFor = { SQLException.class })

          • 명시된 예외일 경우 롤백 처리

          • noRollbackFor 도 있음

        • 프로그래머틱 방법

          • 사용 비추

아래는 클래스 레벨에 적었는데, 메소드 레벨에서도 작성이 가능하다. interface 에도 지정 가능하다.

주의 사항

Transactions 과 Proxies

  • Spring은 @Transactional 이 달린 모든 class 또는 method 에 대해 프록시를 생성

    • 전 후로 트랜잭션 로직 (begin & commit) 발동 시킴

  • 자체 호출은 트랜잭션 작동 x (즉, 프록시가 들어오는 외부 메서드 호출만 가로채게 됩니다)

  • public 메서드만 @Transactional 사용 가능

  • 인터페이스에 @Transactional를 지정하는 것을 비추하지만, Spring Data 의 @Repository 같은 경우 에는 수용된다.

참고자료

  • https://www.baeldung.com/transaction-configuration-with-jpa-and-spring

  • https://www.baeldung.com/spring-transactional-propagation-isolation

Last updated