Transaction propagation REQUIRES_NEW
출처 : 인프런 김영한님의 강의 “스프링 DB 2편 - 데이터 접근 활용 기술” 중 일부
🚫 아래 내용은 주관적인 생각이므로 사실과 다를 수 있습니다.
개요
Spring의 Transation Propagation(전파) 전략 중
REQUIRES_NEW 옵션에 대한 내용
내용
요약
REQUIRES_NEW는 기존 트랜잭션의 DB 커넥션과는
별도의 DB 커넥션을 사용하고 싶을 때 쓰는 옵션이다.
설명
좀 더 구체적인 설명을 위해
외부, 내부 트랜잭션이라는 표현을 사용해보겠다.
- 첫번째 트랜잭션(외부)이 시작
- 첫번째 트랜잭션(외부)이 종료되기 전에
REQUIRES_NEW 전파 전략을 사용하는 두 번째 트랜잭션(내부) 시작 - 두 번째 트랜잭션(내부) 롤백
- 첫번째 트랜잭션(외부) 종료
앞서 말했듯 내부 트랜잭션이 REQUIRES_NEW 전파 전략을 사용하는 경우,
외부와 내부 트랜잭션이 각각 별도의 DB 커넥션을 사용하므로
내부 트랜잭션이 롤백되는 경우에도 외부 트랜잭션에는 영향을 주지 않는다.
세부 사항
조금 더 자세히 들여다보자면,
- 외부 트랜잭션 시작
- 트랜잭션 매니저가 데이터소스를 통해 커넥션을 생성
- 외부 트랜잭션이 DB 커넥션0(conn0)을 획득
- manual commit으로 변경(con.setAutoCommit(false))해 물리 트랜잭션 시작
- 트랜잭션 매니저가 트랜잭션 동기화 매니저에 커넥션을 보관
- 외부 트랜잭션은 신규 트랜잭션(isNewTransaction() = true)
- 로직을 수행하는 과정에서 커넥션이 필요한 경우,
트랜잭션 동기화 매니저를 통해 트랜잭션이 적용된 커넥션을 획득해 사용
- 내부 트랜잭션 시작(REQUIRES_NEW 전파 전략)
- 트랜잭션 매니저는 REQUIRES_NEW 옵션을 확인하고,
기존(외부) 트랜잭션에 참여하는 것이 아닌 별개의 신규 트랜잭션을 시작- 트랜잭션 매니저가 데이터소스를 통해 커넥션을 생성
- 내부 트랜잭션이 DB 커넥션1(conn1)을 획득
- manual commit으로 변경(con.setAutoCommit(false))해 물리 트랜잭션 시작
- 트랜잭션 매니저가 트랜잭션 동기화 매니저에 커넥션을 보관
- 이 때, conn0은 잠시 보류되고,
내부 트랜잭션이 완료 될 때까지 conn1이 사용된다 5. 내부 트랜잭션 또한 신규 트랜잭션(isNewTransaction() = true) 6. 로직을 수행하는 과정에서 커넥션이 필요한 경우,
트랜잭션 동기화 매니저를 통해 conn1 커넥션을 획득해 사용
- 트랜잭션 매니저는 REQUIRES_NEW 옵션을 확인하고,
- 내부 트랜잭션 롤백
- 트랜잭션 매니저를 통해 내부 트랜잭션을 롤백한다.
- 내부 트랜잭션은 신규 트랜잭션이라 실제 물리 트랜잭션을 롤백함
- 내부 트랜잭션은 커넥션1(conn1)을 사용하므로 conn1에 물리 롤백을 수행
- 트랜잭션이 종료되고, conn1는 종료되거나 커넥션 풀에 반납된다.
- 이 때, conn0의 보류가 끝나고, 다시 conn0을 사용한다.
- 트랜잭션 매니저를 통해 내부 트랜잭션을 롤백한다.
- 외부 트랜잭션 커밋
- 트랜잭션 매니저를 통해 외부 트랜잭션을 롤백한다.
- 외부 트랜잭션은 신규 트랜잭션이라 실제 물리 트랜잭션을 커밋함
- ‘rollbackOnly’ 설정이 없으므로 커밋을 진행한다
- 외부 트랜잭션은 커넥션0(conn0)을 사용하므로 conn0에 물리 커밋을 수행
- 트랜잭션이 종료되고, conn0는 종료되거나 커넥션 풀에 반납된다.
- 트랜잭션 매니저를 통해 외부 트랜잭션을 롤백한다.
주의사항
별도의 커넥션을 사용하므로,
DB 커넥션의 수가 늘어난다는 점을 인지하고 사용해야한다.
댓글남기기