이전의 포스팅에서 스프링 트랜잭션 전파에 대해 알아보았다.
스프링 트랜잭션에는 원칙이 있었는데,
논리 트랜잭션중 하나라도 롤백이되면 물리 트랜잭션은 롤백이 되어야 하고,
모든 논리 트랜잭션이 커밋이 되어야 물리 트랜잭션도 커밋이 된다고 하였다.
그렇다면 트랜잭션 별로 커밋과 롤백을 각각 따로 적용시키려면 어떻게 해야할까?
트랜잭션 별로 커밋과 롤백을 분리해서 수행하려면 어떻게 해야할까?
물리 트랜잭션을 분리하면 된다. 그럼 각 트랜잭션 별로 커밋과 롤백을 별도로 수행할 수 있게 된다.
즉, 커넥션을 새로 획득하는 것이다.
코드로 확인해보자
@Test
void inner_rollback_requires_new() {
log.info("외부 트랜잭션 시작");
TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("outer.isNewTransaction()={}", outer.isNewTransaction());
log.info("내부 트랜잭션 시작");
// requires_new 옵션을 부여하여
// 새로운 물리 트랜잭션을 생성함
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus inner = txManager.getTransaction(definition);
log.info("inner.isNewTransaction()={}", inner.isNewTransaction()); // true
log.info("내부 트랜잭션 롤백");
txManager.rollback(inner);
log.info("외부 트랜잭션 커밋");
txManager.commit(outer);
}
결과를 확인해보면
덕분에 내부 트랜잭션이 롤백되더라도 외부 트랜잭션은 커밋을 수행할 수 있게 되었다.
REQUIRES_NEW라는 속성을 이용해 외부 트랜잭션과 내부 트랜잭션을 분리하여 처리할 수 있게되었다.
다만, 이 경우 커넥션이 동시에 2개가 사용된다는 점을 주의해야 한다.
- 50명이 사용할 경우 100개의 커넥션이 점유가 된다.
가장 많이 사용하는 옵션, 필수이므로 없으면 생성, 있으면 참여한다.
기존 트랜잭션 없음: 새로운 트랜잭션을 생성한다.
기존 트랜잭션 있음: 기존 트랜잭션에 참여한다.
항상 새로운 트랜잭션을 생성한다.
기존 트랜잭션 없음: 새로운 트랜잭션을 생성한다.
기존 트랜잭션 있음: 새로운 트랜잭션을 생성한다.
트랜잭션을 지원한다는 뜻이다. 기존 트랜잭션이 없으면, 없는대로 진행하고, 있으면 참여한다.
기존 트랜잭션 없음: 트랜잭션 없이 진행한다.
기존 트랜잭션 있음: 기존 트랜잭션에 참여한다.
트랜잭션을 지원하지 않는다는 의미이다.
기존 트랜잭션 없음: 트랜잭션 없이 진행한다.
기존 트랜잭션 있음: 트랜잭션 없이 진행한다. (기존 트랜잭션은 보류한다
의무사항이라는 뜻으로 없으면 예외 발생, 있으면 참여한다.
기존 트랜잭션 없음: IllegalTransactionStateException 예외 발생
기존 트랜잭션 있음: 기존 트랜잭션에 참여한다.
MANDATORY와 반대이다. 없으면 트랜잭션 없이 진행, 있으면 예외 발생
기존 트랜잭션 없음: 트랜잭션 없이 진행한다.
기존 트랜잭션 있음: IllegalTransactionStateException 예외 발생
중첩된 이라는 뜻으로 내부는 외부에 영향을 받지만 외부는 내부에 영향을 받지 않는다.
기존 트랜잭션 없음: 새로운 트랜잭션을 생성한다.
기존 트랜잭션 있음: 중첩 트랜잭션을 만든다.
isolation , timeout , readOnly는 트랜잭션이 처음 시작될 때만 적욛되고, 기존 트랜잭션에 참여하는 경우에는 적용되지 않는다.
따라서 REQUIRED에서 외부 트랜잭션의 시작, REQUIRED_NEW를 통한 시작 시점에만 적용이 된다.
이것으로 스프링 트랜잭션 전파에 대해 깊이 있게 알아볼 수 있었다. 다음 포스팅에서는 이런 트랜잭션 전파를 어디에 적용할 수 있는지 알아보도록 하자.
출처 : 김영한 - 스프링 DB 2편