스프링 트랜잭션 전파5 - 외부 롤백

학습 페이지

이번엔 내부 트랜잭션은 커밋되는데 외부 트랜잭션이 롤백되는 상황을 살펴보자.

참고로 결론부터 말하면 논리 트랜잭션이 하나라도 롤백되면 전체 물리트랜잭션은 롤백된다고 했다.

image.png

    @Test
    void outer_rollback(){
        log.info("외부 트랜잭션 시작");
        TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute());
        //외부 트랜잭션인지 확인
        log.info("outer.isNewTransaction()={}", outer.isNewTransaction());

        log.info("내부 트랜잭션 시작");
        TransactionStatus inner = txManager.getTransaction(new DefaultTransactionAttribute());
        //내부 트랜잭션인지 확인
        log.info("inner.isNewTransaction()={}", inner.isNewTransaction());

        log.info("내부 트랜잭션 커밋");
        txManager.commit(inner);

        log.info("외부 트랜잭션 롤백");
        txManager.rollback(outer);
    }

image.png

실제로 코드를 돌려보면 전체 트랜잭션이 롤백되는걸 확인할 수 있다. 사실 내부 트랜잭션은 물리 트랜잭션에 관여할 수 없기 때문에 전체가 롤백되는걸 막을 수 없다.. 그래서 외부가 롤백되면 내부도 롤백된다.

그럼 이제 반대로 외부가 커밋인데 내부가 롤백될때는 어떤일들이 일어날까?

스프링 트랜잭션 전파6 - 내부 롤백

학습 페이지

image.png

내부 트랜잭션은 물리트랜잭션과 관련이 없으므로 내부의 롤백이 아무런 영향을 주지 않을 것 같다. 하지만 전에 살펴본 원칙은 하나의 논리 트랜잭션이라도 롤백되면 물리 트랜잭션은 롤백된다는 것이었음. 어떤게 맞는걸까?

    @Test
    void inner_rollback(){
        log.info("외부 트랜잭션 시작");
        TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute());
        //외부 트랜잭션인지 확인
        log.info("outer.isNewTransaction()={}", outer.isNewTransaction());

        log.info("내부 트랜잭션 시작");
        TransactionStatus inner = txManager.getTransaction(new DefaultTransactionAttribute());
        //내부 트랜잭션인지 확인
        log.info("inner.isNewTransaction()={}", inner.isNewTransaction());

        log.info("내부 트랜잭션 롤백");
        txManager.rollback(inner);

        log.info("외부 트랜잭션 커밋");
        txManager.commit(outer);
    }

테스트를 실행해보면 기존 테스트들과는 달리 예외가 발생하며 테스트가 실패한다.