[Sping Boot] EventListener Transactinal 이슈

SOUTH DARIA·2022년 2월 8일
0

EventListener를 걸고, 다른 로직 복붙을 하다가 @TransactionalEvent 어노테이션을 걸었음.

point를 주고 user 관련 테이블에 pointId 업데이트를 해주는 로직을 짜고있었다.
point와 user는 다른 클래스에서 사용되고 있기 때문데 event를 통해서 통신하도록 처리했는데,
point를 주고 해당 pointId가 해당 테이블에 update가 되어야하는데, 되지 않는 현상이 발생했다.
point는 생성되어 db에 insert가 된 상태였다.

한동안 머리를 부여잡고, 고민하다가 이유를 발견했다.

사유는 EventListener에 아래 어노테이션을 붙였기 때문이다.

@Transactional(propagation = Propagation.REQUIRES_NEW)

point 관련 service에서 transaction이 끝나고 point에 대한 컨텍스트가 닫혀 영속성이 제거됨.(메모리에 올라간 point가 없어서 commit이 되지 않음.)
이전에 짰던 코드를 복붙하다가 새로운 트랙잭션을 열어버렸다.

아래 propagation 옵션

Propagation.REQUIRED
트랜잭션이 존재하면 기존의 트랜잭션이 전파된다. 만약 존재하지 않는다면 트랜잭션을 새로 시작한다.

Propagtion.REQUIRES_NEW
매번 새로운 트랜잭션을 생성한다.

propagation = Propagation.REQUIRES_NEW 를 Propagation.REQUIRED 로 바꿔주어 해결하였다.

이후 메모리에 올라간 point가 컨텍스트에서 제거되지 않아 pointId가 user 관련 테이블에 업데이트됨.

어떤 경우에 REQUIRES_NEW 레벨을 사용하는 것이 좋을까?

  • 부모 트랜잭션에서 Exception이 발생해도 커밋이 되어야 하는 경우
  • 부모 트랜잭션에서 자식 트랜잭션을 try - catch 하고 싶은 경우 (일반 트랜잭션으로 하면 try - catch가 롤백 마킹때문에 의도대로 작동하지 않음)
  • 등등....
profile
고양이와 함께 - 끄적끄적 개발하고 이씁니다 ~!

0개의 댓글