스프링 트랜잭션 전파1 - 커밋, 롤백

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("트랜잭션 롤백 완료");
    }
}

스프링 트랜잭션 전파2 - 트랜잭션 두 번 사용

이번에는 트랜잭션이 각각 따로 사용되는 경우를 확인해보자. 이 예제는 트랜잭션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


트랜잭션2


주의!

로그를 보면 트랜잭션1과 트랜잭션2가 같은 conn0 커넥션을 사용중이다. 이것은 중간에 커넥션 풀 때문에 그런 것이다. 트랜잭션1은 conn0 커넥션을 모두 사용하고 커넥션 풀에 반납까지 완료했다. 이후에 트랜잭션2가 conn0 를 커넥션 풀에서 획득한 것이다. 따라서 둘은 완전히 다른 커넥션으로 인지하는 것이 맞다.