BasicTxTest
package hello.springtx.propagation;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import javax.sql.DataSource;
@Slf4j
@SpringBootTest
public class BasicTxTest {
@Autowired
PlatformTransactionManager txManager;
@TestConfiguration
static class Config {
// 원래 스프링이 자동 등록해주지만, 내가 이렇게 직접 등록하게 되면, 이걸 사용하게 된다.
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
@Test
void commit() {
log.info("트랜잭션 시작"); // 트랜잭션 시작할 때 커넥션을 가져온다.
TransactionStatus status = txManager.getTransaction(new DefaultTransactionAttribute());// 이렇게하면 트랜잭션 시작함
log.info("트랜잭션 커밋 시작");
txManager.commit(status);
log.info("트랜잭션 커밋 완료");
}
@Test
void rollback() {
log.info("트랜잭션 시작"); // 트랜잭션 시작할 때 커넥션을 가져온다.
TransactionStatus status = txManager.getTransaction(new DefaultTransactionAttribute());// 이렇게하면 트랜잭션 시작함
log.info("트랜잭션 롤백 시작");
txManager.rollback(status);
log.info("트랜잭션 롤백 완료");
}
}
이번에는 트랜잭션이 각각 따로 사용되는 경우를 확인해보자. 이 예제는 트랜잭션1이 완전히 끝나고나서 트랜잭션2를 수행한다.
double_commit() - BasicTxTest 추가
@Test
void double_commit() {
log.info("트랜잭션1 시작");
TransactionStatus tx1 = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("트랜잭션1 커밋");
txManager.commit(tx1);
log.info("트랜잭션2 시작");
TransactionStatus tx2 = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("트랜잭션2 커밋");
txManager.commit(tx2);
}
트랜잭션 1
Acquired Connection [HikariProxyConnection@1064414847 wrapping conn0] for JDBC transaction
conn0
커넥션을 획득했다.Releasing JDBC Connection [HikariProxyConnection@1064414847 wrapping conn0] after transaction
conn0
커넥션을 반납했다.트랜잭션2
Acquired Connection [HikariProxyConnection@ 778350106 wrapping conn0] for JDBC transaction
conn0
커넥션을 획득했다.Releasing JDBC Connection [HikariProxyConnection@ 778350106 wrapping conn0] after transaction
conn0
커넥션을 반납했다.주의!
로그를 보면 트랜잭션1과 트랜잭션2가 같은 conn0
커넥션을 사용중이다. 이것은 중간에 커넥션 풀 때문에 그런 것이다. 트랜잭션1은 conn0
커넥션을 모두 사용하고 커넥션 풀에 반납까지 완료했다. 이후에 트랜잭션2가 conn0
를 커넥션 풀에서 획득한 것이다. 따라서 둘은 완전히 다른 커넥션으로 인지하는 것이 맞다.