프로그래밍 공부/Spring

스프링 트랜잭션 전파속성

트랜잭션 전파 속성이란?

@Transactional 어노테이션(선언적 트랜잭션)을 사용하면 6가지 속성을 지정해 트랜잭션을 세부적으로 이용할 수 있다.

  • readOnly
  • isolation
  • propagation
  • timeout
  • rollbackFor, noRollbackFor (트랜잭션 롤백/커밋 예외)

이중 Propagation은 새로운 트랜잭션을 시작할지 기존의 트랜잭션에 참여할지 등 트랜잭션의 진행 방식에 대한 내용을 결정하게 된다. Spring이 지원하는 전파속성은 다음의 7가지이다. 

 

  • REQUIRED
  • SUPPORTS
  • MANDATORY
  • REQUIRES_NEW
  • NOT_SUPPORTED
  • NEVER
  • NESTED

물리 트랜잭션과 논리 트랜잭션

  • 물리 트랜잭션 : 실제 커넥션 객체를 사용하여 DB에 적용되는 트랜잭션으로, 커넥션을 통해 commit이나 rollback이 진행되는 단위.
  • 논리 트랜잭션 : 스프링이 트랜잭션 매니저를 통해 트랜잭션을 처리하는 단위

이미지 출처 : https://mangkyu.tistory.com/269

 

 

전파속성 종류

REQUIRED

  • 디폴트 속성으로, 미리 시작된 트랜잭션이 있으면 참여하고 없으면 새로 시작한다.
  • 가장 간단하고 자연스러운 트랜잭션 전파 방식이지만 매우 강력하며 유용하다.
  • 만약 REQUIRED 속성일 때 하나의 트랜잭션이 시작된 후 다른 트랜잭션 경계가 설정된 메소드를 호출하면 자연스럽게 같은 트랜잭션으로 묶인다. 즉, 새로운 물리 트랜잭션을 사용하지 않는다.
    • 그렇기 때문에 논리 트랜잭션 중 (부모, 자식) 하나라도 롤백된다면 모두 롤백되게 된다.

REQUIRES_NEW

  • 항상 새로운 트랜잭션을 시작해야 하는 경우에 사용할 수 있다.
    • 서로 다른 물리 트랜잭션이기 때문에 다른 트랜잭션의 롤백에 영향을 받지 않는다. 
  • 만약 이미 시작된 트랜잭션이 있으면 트랜잭션을 잠시 보류시킨다.
    • 만약 JPA 트랜잭션 매니저를 사용한다면 서버의 트랜잭션 매니저에 트랜잭션 보류가 가능하도록 설정되어 있어야 한다.

SUPPORTS

  • 이미 시작 물리 트랜잭션이 있으면 참여하고, 그렇지 않으면 트랜잭션 없이 진행하게 만든다.
  • 트랜잭션이 없기는 하지만 해당 경계 안에서 Connection 객체나 하이버네이트의 Session 등은 공유를 할 수 있다.

MANDATORY

  • 이미 시작된 트랜잭션이 있으면 참여한다.
  • 하지만 트랜잭션이 시작된 것이 없으면 새로 시작하는 대신 예외를 발생시킨다.
  • 혼자서 독립적으로 트랜잭션을 진행하면 안되는 경우에 사용할 수 있다.

NOT_SUPPORTED

  • 트랜잭션 자체를 지원하지 않고, 트랜잭션이 없이 진행하는 것을 의미한다.
  • 이미 진행중인 트랜잭션이 있으면 이를 보류시키고, 트랜잭션을 사용하지 않도록 한다.

NEVER

  • 이미 진행중인 트랜잭션이 있으면 예외를 발생시키며, 트랜잭션을 사용하지 않도록 강제한다.

NESTED

  • NESTED는 이미 진행중인 트랜잭션이 있으면 중첩 트랜잭션을 시작한다.
    • 중첩 트랜잭션
      • 트랜잭션 안에 다시 트랜잭션을 만드는 것
      • 독립적인 트랜잭션을 만드는 REQUIRES_NEW와는 다르다.
      • NESTED에 의한 중첩 트랜잭션은 먼저 시작된 부모 트랜잭션의 커밋과 롤백에는 영향을 받지만, 자신의 커밋과 롤백은 부모 트랜잭션에게 영향을 주지 않는다.
  • 부모의 트랜잭션은 자식의 작업에 영향을 줘야하지만 자식의 트랜잭션은 부모에 영향을 주지 않아야 할 때 NESTED 전파 속성을 이용할 수 있다.
  • ex) 어떤 중요한 작업을 진행하면서 작업 로그를 DB에 저장해야 한다고 해보자. 그런데 로그를 저장하는 작업은 실패를 하더라도 메인 작업의 트랜잭션까지는 롤백하지 말아야 하는 경우가 있다. 왜냐하면 힘들게 처리한 중요한 작업을 로그를 남기지 못해서 모두 실패로 만들 수 없기 때문이다. 반면에 핵심 작업에서 예외가 발생한다면 이때는 저장된 로그도 제거해야 한다.

이미지 출처 : https://mangkyu.tistory.com/269

 

참고자료

https://mangkyu.tistory.com/269

 

https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#tx-propagation