Published on

Spring Transaction propagation(전파) 옵션

Authors
  • avatar
    Name
    ywj9811
    Twitter

트랜잭션 전파 옵션

REQUIRED_NEW

외부 트랜잭션과 내부 트랜잭션을 완전히 분리해서 각각 별도의 물리 트랜잭션을 사용하는 방법이다.

즉 커밋과 롤백도 각각 일어나게 된다.

따라서 내부 트랜잭션에서 롤백을 하게 되어도 외부 트랜잭션에는 영향을 끼치지 않는다.

물론 반대의 경우도 마찬가지이다.

propagation16

이렇게 물리 트랜잭션을 분리하기 위해서는 내부 트랜잭션을 시작할 때 REQUIRES_NEW 옵션을 사용하면 된다.

이는 새로운 DB 커넥션을 가진다는 뜻이다.

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

	log.info("내부 트랜잭션 시작");
	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); //커밋
	/**
	* 이 경우 PROPAGATION_REQUIRES_NEW 에 의해서 내부의 경우에 트랜잭션을 새로 생성하기 때문에 롤백이 되어도 커밋이 되게 된다.
	* 각각 작동하게 됨
	*/
}

위의 코드를 살펴보면 innerPROPAGATION_REQUIRES_NEW 를 적용시켰다.

이 옵션은 새로운 물리 트랜잭션을 만들어서 시작하게 하는 것이다.

propagation17

위와 같은 결과가 나오게 되는데, 살펴보면 외부 트랜잭션의 경우 conn0 이 생성되며 내부 트랜잭션이 시작될 때 conn1 이 새롭게 생성되는 모습을 확인할 수 있다.

따라서 conn1 이 롤백을 진행하여도 conn0 은 다른 커넥션이기 때문에 커밋을 진행할 수 있는 것이다.

propagation18

이와 같이 진행이 되게 된다.

즉 두개의 물리 트랜잭션이 동작하게 된다.

RQUIRES_NEW 옵션을 사용하면 물리 트랜잭션이 명확하게 분리되지만

⚠️데이터베이스 커넥션이 동시에 2개 사용된다는 점을 유의해야 한다!⚠️

그 외 다양한 옵션들

전파 옵션을 별도로 지정하지 않으면 디폴트로 REQUIRED 가 적용이 된다.

  • REQUIRED : 가장 많이 사용하는 기본 설정으로 기존 트랜잭션이 없으면 생성하고 있다면 참여한다.
  • REQUIRES_NEW : 항상 새로운 트랜잭션을 생성한다.

이 외에 나머지는 거의 사용하지 않으니 존재만 알고 있으면 된다.

  • SUPPORT : 트랜잭션을 지원한다는 뜻으로 기존 트랜잭션이 없으면 없는대로 진행하고 있으면 참여한다.
  • NOT_SUPPORT : 트랜잭션을 지원하지 않는다는 의미로 기존에 있어도 없어도 없이 진행한다.
  • MANDATORY : 의무 사항으로 기존 트랜잭션이 무조건 있어야 한다는 뜻이다. 만약 기존 트랜잭션이 없다면 예외가 발생한다.
  • NEVER : 트랜잭션을 사용하지 않는다는 의미로 만약 기존에 트랜잭션이 있다면 예외가 발생한다.
  • NESTED : 중첩 트랜잭션 → 새로운 트랜잭션을 만들지만 외부의 트랜잭션에 영향을 받는다. 하지만 외부 트랜잭션에는 영향을 끼칠 수 없다.