시냅스

Spring 트랜잭션 전파 정리 본문

Java, Spring

Spring 트랜잭션 전파 정리

ted k 2022. 9. 3. 17:45

예외와 트랜잭션 커밋, 롤백 정책

  • 예외 발생시 스프링 트랜잭션 AOP 는 예외의 종류에 따라 트랜잭션을 커밋하거나 롤백한다.
    • 언체크 예외인 RuntimeException, Error와 그 하위 예외가 발생하면 트랜잭션을 롤백한다.
      • 개발자가 다루기 어려운 복구 불가능한 문제라는 판단이 이유이다.
    • 체크 예외인 Exception과 그 하위 예외가 발생하면 트랜잭션을 커밋한다.
      • 비즈니스 의미가 있을 때 사용한다.
        • 클라이언트가 행동을 수정/변경한다면 예외를 회피할 수 있을 때를 의미한다.

 

스프링 트랜잭션 전파

  • 트랜잭션이 각각 수행된다면 사용되는 DB 커넥션 또한 각각 다르다

 

 

 

 

 

  • 로직 1에서 트랜잭션을 수행하면서 트랜잭션이 적용된 로직 2를 부른다면,
    • 로직 1은 외부 트랜잭션, 로직 2는 내부 트랜잭션이라고 말할 수 있다.
  • 다만 이해하기 쉽게 로직 1과 로직 2가 모두 끝나는 것을 물리 트랜잭션이라고 부르고,
    • 물리 트랜잭션은 다시 말하자면,
      • 실제 데이터베이스에 적용되는 트랜잭션 
      • setAutoCommit(false)를 하고 실제 커넥션을 통해 커밋, 롤백하는 단위이다.
  • 각각은 논리 트랜잭션 이라고 부를 수 있다.
  • 원칙
    • 모든 논리 트랜잭션이 커밋되어야 물리 트랜잭션이 커밋된다.
    • 하나의 논리 트랜잭션이라도 롤백되면 물리 트랜잭션은 롤백된다.

 

트랜잭션 전파의 요청 흐름

  • 외부 트랜잭션
    • taManager.getTransaction() 을 호출해 트랜잭션을 시작한다.
    • 트랜잭션 매니저는 데이터소스를 통해 커넥션을 생성한다.
    • 생성한 커넥션을 수동 커밋 모드로 설정한다 - 물리 트랜잭션 시작
    • 트랜잭션 매니저는 트랜잭션 동기화 매니저에 커넥션을 보관한다.
    • 트랜잭션 매니저는 트랜잭션을 생성한 결과를 TransactionStatus에 담아서 반환한다.
      • 신규 트랜잭션의 여부가 담겨 있다.
    • 로직 1이 사용되고, 커넥션이 필요한 경우 트랜잭션 동기화 매니저를 통해 트랜잭션이 적용된 커넥션을 획득해서 사용된다.
  • 내부 트랜잭션
    • taManager.getTransaction() 을 호출해 트랜잭션을 시작한다.
    • 트랜잭션 매니저는 트랜잭션 동기화 매니저를 통해서 기존 트랜잭션이 존재하는지 확인한다.
    • 기존 트랜잭션이 존재하므로 기존 트랜잭션에 참여한다.
      • 이미 물리 트랜잭션이 시작되고 있으므로 커넥션을 트랜잭션 동기화 매니저에 담아두었다.
      • 따라서 트랜잭션 동기화 매니저에 보관된 기존 커넥션을 사용하게 된다.
    • 트랜잭션 매니저는 트랜잭션을 생성한 결과를 TransactionStatus에 담아서 반환한다.
      • 이때에는 기존 트랜잭션에 참여했기 때문에 신규 트랜잭션이 아니다.
    • 로직 2가 사용되고, 커넥션이 필요한 경우 트랜잭션 동기화 매니저를 통해 외부 트랜잭션이 보관한 커넥션을 획득해서 사용한다.

 

트랜잭션 전파의 응답 흐름

  • 내부 트랜잭션
    • 로직 2가 끝나고 트랜잭션 매니저를 통해 내부 트랜잭션을 커밋한다.
    • 내부 트랜잭션은 신규 트랜잭션이 아니기 때문에 실제 커밋을 호출하지 않는다.
  • 외부 트랜잭션
    • 로직 1이 끝나고 트랜잭션 매니저를 통해 외부 트랜잭션을 커밋한다.
    • 외부 트랜잭션은 신규 트랜잭션 이기 때문에 실제 DB 커넥션에 커밋을 호출한다.
    • 트랜잭션 매니저에 커밋하는 것이 논리적인 커밋이라면, 실제 커넥션에 커밋하는 것을 물리 커밋이라 한다.
    • 실제 데이터베이스에 커밋이 반영되고 트랜잭션이 종료된다.

 

외부 트랜잭션 롤백의 응답 흐름

  • 내부 트랜잭션
    • 로직 2가 끝나고 트랜잭션 매니저를 통해 내부 트랜잭션을 커밋한다.
  • 외부 트랜잭션
    • 로직 1이 끝나고 트랜잭션 매니저를 통해 외부 트랜잭션을 롤백한다.
    • 신규 트랜잭션 이므로 DB 커넥션에 실제 롤백을 호출한다.

 

내부 트랜잭션 롤백의 응답 흐름

  • 내부 트랜잭션
    • 로직 2가 끝나고 내부 트랜잭션을 롤백한다.
    • 아직 트랜잭션이 끝난 것이 아니기 때문에 실제 롤백을 호출하지 않는다.
    • 내부 트랜잭션은 물리 트랜잭션을 롤백하지 않는 대신에 트랜잭션 동기화 매니저에 rollbackOnly=true 라는 표시를 한다.
  • 외부 트랜잭션
    • 로직 1이 끝나고 외부 트랜잭션을 커밋한다.
    • 외부 커넥션은 신규 트랜잭션이므로 DB 커넥션에 실제 커밋을 해야하는데, 이때 먼저 트랜잭션 동기화 매니저에 rollbackOnly=true 표시가 있는지 확인한다.
    • 롤백 전용 표시가 있으므로 실제 데이터베이스에 롤백이 반영되고, 물리 트랜잭션도 끝난다.
    • 내부에서 예외가 발생되어 롤백이 되었기 때문에 기대값과 다르다.
      • 예외를 통해 롤백이 되었다는 것을 클라이언트에 알려준다.
      • UnexpectedRollbackException으로 런타임 예외를 던진다.
Comments