Transactional

  • 스프링에서 트랜잭션 처리는 보통 @Transactional 어노테이션을 많이 사용하게 된다.
  • @Transactional은 클래스 또는 메서드에 사용할 수 있으며 @Transactional이 포함된 메서드가 호출될 경우, 프록시 객체가 생성된다.
  • 프록시 객체는 해당 메서드 실행 이전에 PlatformTransactionManager를 사용하여 트랜잭션을 시작하고 결과에 따라 Commit 또는 Rollback한다.

Commit과 Rollback은 어느 경우에 발생하는가?

  • CheckedException or 예외가 없을 때는 Commit
  • UncheckedException이 발생하면 Rollback

@Transactional 우선순위는 어떻게 되는가?

  1. 클래스 메서드
  2. 클래스
  3. 인터페이스 메서드
  4. 인터페이스

주의할 점

@Transactional 어노테이션 같은 경우 Spring AOP를 이용하게 되는데 이 AOP는 기본적으로 DynamicProxy를 이용한다. Dynamic Proxy는 인터페이스 기반으로 동작하기 때문에 인터페이스가 없을 경우 트랜잭션이 동작하지 않는다.

  • 인터페이스 없이 트랜잭션 동작하게 하려면 CGLib Proxy를 이용하면 된다. CGLib Proxy는 클래스에 대한 Proxy가 가능하기 때문에 인터페이스가 없어도 된다.
  • Spring 의 코드 삽입 방법은 크게 2가지 방법이 있습니다.
    • 바이트 코드 생성 (CGLIB 사용)
    • 프록시 객체 사용
  • 2가지 방법중 Spring 은 기본적으로 프록시 객체 사용 이 선택됩니다. 그렇기에 interface 가 반드시 필요합니다.SpringBoot 는 기본적으로 바이트 코드 생성 이 선택됩니다. 그렇기에, 굳이 interface 가 필요없습니다.
  • 만약 개발환경이 SpringBoot 라면 Books 인터페이스 없이 봐도 무방합니다.

@Transactinal은 public method에만 적용된다.

  • @Transactional은 프록시 기반으로 동작하기 때문에 public method가 아니면 동작하지 않는다.

동일한 클래스 내의 호출은 @Transactional이 동작하지 않는다.

  • 프록시 기반으로 동작하기 때문에 외부에서 접근할 때 AOP를 통해서 프록시 객체를 접근할 수 있다. 그러나 클래스 내부에서 다른 메서드를 호출하게 되면 프록시로 접근하지 않고 직접 접근하기 때문에 메서드에 선언해 놓은 @Transactional이 정상적으로 동작하지 않는다.
    • 클래스 내부 메서드를 호출하여 @Transactinal을 동작하게 하고 싶다면?
      • 가장 간단한 방법은 새로운 클래스를 생성하여 메서드를 위임하는 것
      • 클래스 생성이 어렵다면 aspectj를 사

'Computer science > Spring' 카테고리의 다른 글

Spring Security  (0) 2023.06.21
@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
영속성 컨텍스트  (0) 2023.06.15
Filter 와 Interceptor  (0) 2023.06.15
OSIV  (0) 2023.06.08

+ Recent posts