트랜잭션이 두 개 이상이면 어떻게 동작하는가?
외부 트랜잭션
내부 트랜잭션
원칙
- 모든 논리 트랜잭션이 커밋되어야 물리 트랜잭션이 커밋된다
- 하나의 논리 트랜잭션이라도 롤백되면 물리 트랜잭션은 롤백된다
rollbackOnly=true
TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("outer.isNewTransaction()={}", outer.isNewTransaction());
setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus inner = txManager.getTransaction(definition);
전파 옵션인 propagationBehavior 에 PROPAGATION_REQUIRES_NEW 을 설정
👉 내부 트랜잭션을 시작할 때 기존 트랜잭션에 참여하는 것이 아니라 새로운 물리
트랜잭션을 만들어서 시작하게 됨
데이터베이스 커넥션이 동시에 2개 사용된다는 점을 주의
기존 트랜잭션 X : 새로운 트랜잭션을 생성
기존 트랜잭션 O : 기존 트랜잭션에 참여
기존 트랜잭션 X : 새로운 트랜잭션을 생성
기존 트랜잭션 O : 새로운 트랜잭션을 생성
기존 트랜잭션 X : 트랜잭션 없이 진행
기존 트랜잭션 O : 기존 트랜잭션에 참여
기존 트랜잭션 X : 트랜잭션 없이 진행
기존 트랜잭션 O : 트랜잭션 없이 진행 (기존 트랜잭션은 보류)
기존 트랜잭션 X : IllegalTransactionStateException 예외 발생
기존 트랜잭션 O : 기존 트랜잭션에 참여
기존 트랜잭션 X : 트랜잭션 없이 진행
기존 트랜잭션 O : IllegalTransactionStateException 예외 발생
기존 트랜잭션 X : 새로운 트랜잭션 생성
기존 트랜잭션 O : 중첩 트랜잭션 생성
💡 isolation
timeout
readOnly
는 트랜잭션이 처음 시작될 때만 적용된다
트랜잭션에 참여하는 경우에는 적용 X
예를 들어 REQUIRED , REQUIRES_NEW 를 통한 트랜잭션 시작 시점에만 적용
REQUIRES_NEW를 사용하지 않고 구조를 분리하는 방법도 있다.
이렇게 하면 동시에 커넥션 2개를 사용하지 않으나,
구조상 REQUIRES_NEW를 사용하는 것이 더 깔끔한 경우도 있음.