Transaction propagation REQUIRES_NEW

태그: , , ,

카테고리:

출처 : 인프런 김영한님의 강의 “스프링 DB 2편 - 데이터 접근 활용 기술” 중 일부


🚫 아래 내용은 주관적인 생각이므로 사실과 다를 수 있습니다.


개요

Spring의 Transation Propagation(전파) 전략 중
REQUIRES_NEW 옵션에 대한 내용


내용

요약

REQUIRES_NEW는 기존 트랜잭션의 DB 커넥션과는
별도의 DB 커넥션을 사용하고 싶을 때 쓰는 옵션이다.


설명

좀 더 구체적인 설명을 위해
외부, 내부 트랜잭션이라는 표현을 사용해보겠다.

  1. 첫번째 트랜잭션(외부)이 시작
  2. 첫번째 트랜잭션(외부)이 종료되기 전에
    REQUIRES_NEW 전파 전략을 사용하는 두 번째 트랜잭션(내부) 시작
  3. 두 번째 트랜잭션(내부) 롤백
  4. 첫번째 트랜잭션(외부) 종료

앞서 말했듯 내부 트랜잭션이 REQUIRES_NEW 전파 전략을 사용하는 경우,
외부와 내부 트랜잭션이 각각 별도의 DB 커넥션을 사용하므로
내부 트랜잭션이 롤백되는 경우에도 외부 트랜잭션에는 영향을 주지 않는다.


세부 사항

조금 더 자세히 들여다보자면,

  1. 외부 트랜잭션 시작
    1. 트랜잭션 매니저가 데이터소스를 통해 커넥션을 생성
    2. 외부 트랜잭션이 DB 커넥션0(conn0)을 획득
    3. manual commit으로 변경(con.setAutoCommit(false))해 물리 트랜잭션 시작
    4. 트랜잭션 매니저가 트랜잭션 동기화 매니저에 커넥션을 보관
    5. 외부 트랜잭션은 신규 트랜잭션(isNewTransaction() = true)
    6. 로직을 수행하는 과정에서 커넥션이 필요한 경우,
      트랜잭션 동기화 매니저를 통해 트랜잭션이 적용된 커넥션을 획득해 사용
  2. 내부 트랜잭션 시작(REQUIRES_NEW 전파 전략)
    • 트랜잭션 매니저는 REQUIRES_NEW 옵션을 확인하고,
      기존(외부) 트랜잭션에 참여하는 것이 아닌 별개의 신규 트랜잭션을 시작
      1. 트랜잭션 매니저가 데이터소스를 통해 커넥션을 생성
      2. 내부 트랜잭션이 DB 커넥션1(conn1)을 획득
      3. manual commit으로 변경(con.setAutoCommit(false))해 물리 트랜잭션 시작
      4. 트랜잭션 매니저가 트랜잭션 동기화 매니저에 커넥션을 보관
      • 이 때, conn0은 잠시 보류되고,
        내부 트랜잭션이 완료 될 때까지 conn1이 사용된다 5. 내부 트랜잭션 또한 신규 트랜잭션(isNewTransaction() = true) 6. 로직을 수행하는 과정에서 커넥션이 필요한 경우,
        트랜잭션 동기화 매니저를 통해 conn1 커넥션을 획득해 사용
  3. 내부 트랜잭션 롤백
    1. 트랜잭션 매니저를 통해 내부 트랜잭션을 롤백한다.
      • 내부 트랜잭션은 신규 트랜잭션이라 실제 물리 트랜잭션을 롤백함
    2. 내부 트랜잭션은 커넥션1(conn1)을 사용하므로 conn1에 물리 롤백을 수행
      • 트랜잭션이 종료되고, conn1는 종료되거나 커넥션 풀에 반납된다.
      • 이 때, conn0의 보류가 끝나고, 다시 conn0을 사용한다.
  4. 외부 트랜잭션 커밋
    1. 트랜잭션 매니저를 통해 외부 트랜잭션을 롤백한다.
      • 외부 트랜잭션은 신규 트랜잭션이라 실제 물리 트랜잭션을 커밋함
    2. ‘rollbackOnly’ 설정이 없으므로 커밋을 진행한다
    3. 외부 트랜잭션은 커넥션0(conn0)을 사용하므로 conn0에 물리 커밋을 수행
      • 트랜잭션이 종료되고, conn0는 종료되거나 커넥션 풀에 반납된다.

주의사항

별도의 커넥션을 사용하므로,
DB 커넥션의 수가 늘어난다는 점을 인지하고 사용해야한다.

댓글남기기