Spring AOP - Transactional, Async

Transactional 전파레벨 관련 실험

실험 환경

  • 로컬에서 docker를 띄워 Slave, Master DB를 구성하였다.

  • Read-Only True시 Slave DB와 연결, Read-Only False시 Master DB와 연결 하도록 구성

 

Transactional Read-Only False 메소드 안에서 Read-Only True인 메소드가 실행된다면?

 

  • 호출 한 메소드 (Read-Only False)에서 연결 된 Master DB와의 Connection을 사용한다.
  • 즉, 조회 쿼리 (Read-Only True)도 Slave를 찌르지 않고, Master DB와의 커넥션을 통해 가져오게 된다.

 

Transactional Read-Only True 메소드 안에서 Read-Only False인 메소드가 실행된다면?

  • Connection is read-only. Queries leading to data modification are not allowed. 에러 발생

 

Transaction 전파 레벨

  • Propagation.REQUIRED
    • 스프링의 기본 전파 레벨
    • 해당 전파레벨의 메소드를 호출한 곳에서 별도의 트랜잭션이 설정되어 있지 않았다면 트랜잭션을 새로 시작
    • 호출한 곳에서 이미 트랜잭션이 설정되어 있다면 기존의 트랜잭션 내에서 로직을 실행
    • 예외가 발생하면 롤백이 되고 호출한 곳에도 롤백이 전파

 

지금까지는 Propagation.REQUIRED로 실행이 되어왔기 때문에, 부모의 트랜잭션 내에서 로직을 실행하였다.

 

REQUIRED_NEW로 전파레벨을 바꾸어본다면?

  • 예외가 발생하지 않고 별개의 커넥션이 생성되었다.

 

  • Propagation.REQUIRED_NEW
    • 매번 새로운 트랜잭션을 시작
    • 새로운 트랜잭션 안에서 예외가 발생해도 호출한 곳에는 롤백이 전파되지 않음
    • 생성된 트랜잭션들은 완전히 독립된 별개의 단위로 작동

 

Spring AOP - Transactional

@Transactional이 없는 메소드에서 자신의 @Transactional이 붙은 메서드를 실행

 

 

  • JPA의 변경감지가 일어나지 않았다.
  • 변경감지
    • Transaction을 Commit하는 순간 영속성 컨텍스트에 있는 엔티티의 변경을 감지
  • Transaction이 걸리지 않았다.

 

@Transactional이 없는 메소드에서 외부 @Transactional이 붙은 메서드를 실행

 

 

  • JPA의 변경감지가 일어났다.

 

트랜잭션의 동작 원리 

  • 스프링 @Transactional은 Proxy를 통해 처리 된다.
  • 트랜잭션 어노테이션이 걸려있는 메소드의 클래스의 프록시 객체가 만들어진다.
  • 프록시 객체의 update에서 트랜잭션 비긴, 커밋, 롤백과 같은 작업이 이루어진다.

 

  • 같은 클래스 내의 메소드를 호출 한 경우 "프록시객체"를 타지 않는다.
  • 자신의 클래스에 있는 update 메소드를 호출한다.

 

 

  • 반면 외부에 있는 메소드를 호출했을 때는 프록시 객체를 타게된다.

 

Async 관련 실험

Read-Only False 메소드에서 @Async로 Read-Only True 메소드를 실행 할 경우

 

  • http-nio-8080-exec-1 쓰레드와, task-1 (@Async)쓰레드가 생성되었다.
  • 그리고 각 쓰레드마다 커넥션이 새로 생성되었으며 Transactional Read-Only 설정에 따라 Master, Slave로 연결이 되었다.

 

@Async Read-Only False 메소드에서 Read-Only True 메소드를 실행

 

 

  • task-1 쓰레드가 생성되었다.
  • 해당 쓰레드에서 가져온 커넥션 (Read-Only False 이기 때문에 Master)로 Read-Only True 메소드인 getUser()가 실행되었다.

 

Read-Only True에서 @Async Read-Only Ture 메소드 실행

 

  • 기존 쓰레드 http-nio-8080-exec-2의 커넥션과 task-2의 커넥션이 별도로 생성된다.
  • 둘 다 Read-Only True여서 Slave DB와 연결되었다.

 

 

Spring AOP - Async

일반 메소드에서 @Async 붙은 메소드를 실행 (같은 클래스)

 

  • 세 메소드가 전부 http-nio-8080-exec6 스레드에서 실행된다.
  • 같은 클래스 내에서 실행한 @Async가 무시되었다.

 

@Async 붙은 메소드에서 @Async 붙은 메소드를 실행 (같은 클래스)

 

 

  • 세 메소드가 전부 task-3 스레드에서 실행된다.
  • 같은 클래스 내에서 실행한 @Async들이 무시가 되었다.

 

결론

  • 같은 클래스 내에서 AOP로 동작하는 어노테이션들 (Transactional, Async)의 호출을 주의하자

댓글



Designed by JB FACTORY