트랜잭션을 사용 중인데 그 안에서도 트랜잭션을 사용하는 경우
둘 이상의 트랜잭션이 만나는 경우
어떻게 동작할까
트랜잭션 매니저는 dataSourceTransactionManager를 사용하기 때문에 다음 설정으로 로그를 남긴다.
logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG
다음 코드는 트랜잭션1을 수행한 후 트랜잭션2를 수행하는 로직이다.
@Test
void double_commit() {
log.info("트랜잭션1 시작");
TransactionStatus tx1 = txManager.getTransaction(new DefaultTransactionDefinition());
log.info("트랜잭션1 커밋");
txManager.commit(tx1);
log.info("트랜잭션2 시작");
TransactionStatus tx2 = txManager.getTransaction(new DefaultTransactionDefinition());
log.info("트랜잭션2 커밋");
txManager.commit(tx2);
}
로그를 보면 서로 conn0 번으로, 같은 커넥션을 사용한 것을 알 수 있다.
단지 커넥션 풀 때문에 일어난 상황이고, 서로 독립된 트랜잭션에서 로직을 수행한다.
-> 트랜잭션이 각각 수행되면서 사용하는 DB커넥션도 다르다.
(스프링은 기본적으로 히카리 커넥션 풀을 HikariDataSource
사용한다.)
히카리 커넥션풀에서 커넥션을 획득하면 실제 커넥션을 그대로 반환하는 것이 아니라 내부 관리를 위해 히카리 프록시 커넥션이라는 객체를 생성해 반환한다. 물론 내부에 실제 커넥션이 포함되어 있지만 프록시 객체의 주소로 획득한 커넥션을 구분할 수 있다.
Acquired Connection [HikariProxyConnection@595382884 wrapping conn0: ...
Acquired Connection [HikariProxyConnection@420967638 wrapping conn0: ...