🍃Spring
[Spring] 트랜잭션 전파 - 1
waveofmymind
2023. 2. 5. 16:42
트랜잭션 전파란?
트랜잭션을 커넥션을 달리해서 각각 사용하는 방법이 아닌 트랜잭션 진행 중, 추가로 트랜잭션을 수행할 경우의 동작을 결정하는 것을 트랜잭션 전파라고 한다.
한 트랜잭션 내에서 새로운 트랜잭션이 추가로 수행될 경우
- 처음 수행되는 트랜잭션을 상대적으로 외부 트랜잭션, 그 트랜잭션 내에서 수행되어야 하는 트랜잭션을 내부 트랜잭션이라고 한다.
- 스프링은 이때 외부 트랜잭션과 내부 트랜잭션을 묶어서 하나의 트랜잭션으로 만들어준다.
물리 트랜잭션, 논리 트랜잭션
- 스프링에서는 위에서 말했던 외부 트랜잭션과 내부 트랜잭션을 논리 트랜잭션, 그것을 하나로 묶은 트랜잭션을 물리 트랜잭션이라고 한다.
- 우리가 알고 있는 DB에 커밋,롤백되는 트랜잭션을 물리 트랜잭션이라고 하고, 트랜잭션 매니저를 통해 트랜잭션을 사용하는 단위라고 생각하면 된다.
- 위 개념은 트랜잭션 진행중 내부에서 새로운 트랜잭션이 수행되어야 할 때에만 사용되는 개념이다.
- 물리 트랜잭션, 논리 트랜잭션은 아래와 같은 원칙을 만들기 위해 도입되었다.
- 모든 논리 트랜잭션이 커밋되어야 물리 트랜잭션이 커밋된다.
- 하나의 논리 트랜잭션이라도 롤백될 경우, 물리 트랜잭션은 롤백된다.
- 모든 트랜잭션 매니저가 커밋되어야 물리 트랜잭션이 커밋될 수 있다는 것이다.
트랜잭션 전파 예제
다음과 같이 테스트 코드로 트랜잭션 전파를 알아볼 수 있다.
inner_commit()
@Test
void inner_commit() {
log.info("외부 트랜잭션 시작");
TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("outer.isNewTransaction()={}",outer.isNewTransaction());
log.info("내부 트랜잭션 시작");
TransactionStatus inner = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("inner.isNewTransaction()={}", inner.isNewTransaction());
log.info("내부 트랜잭션 커밋");
txManager.commit(inner);
log.info("외부 트랜잭션 커밋");
txManager.commit(outer);
}
- 외부 트랜잭션이 수행중 내부 트랜잭션이 수행되는 과정이다.
- isNewTransaction(): 해당 트랜잭션이 새로운 트랜잭션일 경우 True, 아닐경우 False를 반환한다.
- outer.isNewTransaction()의 경우 새로운 트랜잭션이기 때문에 True
- inner.isNewTransaction()의 경우 외부 트랜잭션에 참여한 것이기 때문에 False를 반환한다.
- 참여라는 것은 내부 트랜잭션이 외부 트랜잭션을 이어 받는다는 뜻이다.(범위가 넓어진다.)
실행 결과
외부 트랜잭션 시작
Creating new transaction with name [null]:
PROPAGATION_REQUIRED,ISOLATION_DEFAULT
Acquired Connection [HikariProxyConnection@1943867171 wrapping conn0] for JDBC
transaction
Switching JDBC Connection [HikariProxyConnection@1943867171 wrapping conn0] to
manual commit
outer.isNewTransaction()=true
내부 트랜잭션 시작
Participating in existing transaction
inner.isNewTransaction()=false
내부 트랜잭션 커밋
외부 트랜잭션 커밋
Initiating transaction commit
Committing JDBC transaction on Connection [HikariProxyConnection@1943867171
wrapping conn0]
Releasing JDBC Connection [HikariProxyConnection@1943867171 wrapping conn0]
after transaction
- Participating in existing transaction: 내부 트랜잭션이 시작되고, 진행되던 외부 트랜잭션에 참여하는 것을 알 수 있다.
- 내부 트랜잭션 커밋 로그가 나오지만, txManager.commit(inner)의 로그가 나오지 않았는데 외부 트랜잭션 커밋 로그가 나왔다.
- 한 트랜잭션당 커밋은 한번 수행되어져야 하므로, 외부 트랜잭션만 물리 트랜잭션을 시작하고, 커밋했다.
- 내부 트랜잭션이 커밋될 경우, 외부 트랜잭션의 결과가 커밋될 수 없기 때문이다.
- 이를 통해 처음 시작한 외부 트랜잭션이 실제 물리 트랜잭션을 관리하도록 되어있다는 것을 알 수 있다.
출처
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-2/dashboard
스프링 DB 2편 - 데이터 접근 활용 기술 - 인프런 | 강의
백엔드 개발에 필요한 DB 데이터 접근 기술을 활용하고, 완성할 수 있습니다. 스프링 DB 접근 기술의 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., - 강의 소개 | 인
www.inflearn.com