카테고리 없음

Spring Transaction 전파 규칙

혜wony 2023. 6. 2. 14:28

내부 프로젝트중 트랜잭션이 문제를 일으켜 열심히 찾아봤다.

문제 발생

배치 프로그램의 시작과 동시에 로그 테이블에 로그가 찍혀야 하는데 한 스탭이 다 돌고 종료시 로그가 찍힘.

만약 문제가 있어서 중간에 비정상 종료시 로그테이블에 남지도 않음 

소스상 구현은 이미 오류가 날시 로그테이블에 에러로그까지 남기도록 구현되어 있으나 이는 중간에 비정상 종료시에는 볼 수 없음.

 

이와 관련해서 Spring Data JPA 와 스프링 배치 관련해서도 작성해 봐야겠다.

 결론적으로 나는 기존 소스에는 service 단없이 repository를 바로 호출하여 사용하고 있는것을

service단으로 분리하고 

@Transactional(propagation = Propagation.NOT_SUPPORTED)

을 주어서 이를 해결 하였다.

전파규칙에대해 더욱 자세히 알아보자.!!

 

Spring에서는 Transaction이 걸려있는 메소드에서 Transaction 걸려있는 또 다른 메소드를 호출할 때 Transaction이 어떻게 전파될 것인지 결정할 수 있다.

 

다만 이것은 같은 클래스의 메소드끼리는 해당이 없다. 같은 클래스 내의 메소드 호출시에는 Transaction이 걸려있더라도 그냥 최초 호출한 시점에 시작된 Transaction만으로 진행된다.

@Transactional

기본속성이다. 기존에 생성된 Transaction이 있으면 참여하고 없다면 새로운 Transaction을 생성한다.
이는 결국 @Transactional(propagation = Propagation.REQUIRED) 를 의미한다.

@Transactional(propagation = Propagation.REQUIRES_NEW)

항상 새로운 Transaction을 생성한다.

 

@Transactional(propagation = Propagation.SUPPORTS)

기존에 생성된 중인 Transaction 이 있을 때만 참여하고 없다면 Transaction 없이 진행한다.

 

@Transactional(propagation = Propagation.NOT_SUPPORTED)

기존에 생성된 Transaction 이 있든 말든 Transaction 없이 진행한다.

 

@Transactional(propagation = Propagation.MANDATORY)

이미 진행 중인 Transaction이 있으면 참여한다. 반면에 기존에 생성된 Transaction 이 없다면 예외를 발생시킨다.

※ 혼자서는 독립적으로 트랜잭션을 진행하면 안 되는 경우에 사용한다.

 

@Transactional(propagation = Propagation.NESTED)

이미 진행 중인 Transaction이 있다면 중첩으로 Transaction이을 생성해서 진행한다. 중첩된 Transaction은 먼저 시작된 부모 Transaction의 commit과 rollback에는 영향을 받지만 자신의 commit과 rollback은 부모 Transaction에 영향을 주지 않는다.

 

@Transactional(propagation = Propagation.NEVER)

Transaction 없이 진행한다. 이미 진행 중인 Transaction이 있으면 예외를 발생시킨다.