[JPQL transaction 에러] org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query

RyECODING·2025년 5월 16일
0

Trouble Shooting

목록 보기
13/13

✅ 상황

커뮤니티 서비스를 만들고 있었다.
커뮤니티 내의 게시글 조회 시 댓글 수도 함께 노출해줘야 한다.
게시글 entity에 commentCount 칼럼을 추가하고 변경 시에 숫자를 업데이트하는 방식으로 로직을 구성했는데,,!!!

위와 같은 에러가 떴다.
트랜잭션이 없다는 에러다.
구글링을 했을 때는 repository의 메서드에 @Transactional을 붙여주면 된다고 했지만, 여전했다.

제일 바깥쪽인 eventHandler에 @Transactional 을 붙여주었을 때는, @TransactionalEventListener@Transactional을 같이 쓰면 안된다는 에러가 떴다.


✅ 해결

그래서 해결 방법은 바로!!
@Transactional(propagation = Propagation.REQUIRES_NEW)을 붙여주는 것이다.
그냥 @Transactional은 트랜잭션이 없을 경우 에러가 나버리는데, @Transactional(propagation = Propagation.REQUIRES_NEW)은 새로운 트랜잭션을 발생시키기 때문에 (propagation = Propagation.REQUIRES_NEW)을 꼭 붙여줘야한다!

  • @Transactional + @TransactionalEventListener 에러가 나는 이유 :
    @TransactionalEventListener는 이전 트랜잭션이 끝나면 이벤트 실행, 즉 현재 트랜잭션이 끝난 상태인데 @Transactional은 트랜잭션이 없으면 에러가 난다.
    즉, 둘이 같이 만나면 에러가 나는 것이다.

그래서 @Transactional(propagation = Propagation.REQUIRES_NEW)으로 새로운 트랜잭션을 발생시킨다고 명시해줘야하는 것이다!

  • 많은 블로그에서 repository의 메서드에 @Transactional을 붙여주면 된다고 하는데 아니다..!
    제일 바깥쪽에 붙여주는 것이 좋기 때문에 이 경우 eventHandler에 붙여주었다.

🩵 해결 코드

@Component
@RequiredArgsConstructor
public class CommentEventHandler {

    private final PostPort postPort;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @TransactionalEventListener
    public void handleCommentEvent(CommentCreatedEvent event) {
        postPort.increaseCommentCount(event.postId());
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @TransactionalEventListener
    public void handleCommentEvent(CommentDeletedEvent event) {
        postPort.decreaseCommentCount(event.postId());
    }
}
profile
례코드

0개의 댓글