문제 상황
게시글 조회 시 조회수가 증가하지 않는 문제가 발생했다.
JPA의 변경 감지(Dirty Checking)를 사용하여 viewCount를 증가시키도록 구현했으나 viewCount가 1에서 더 이상 증가하지 않았다.
▶ 문제가 발생한 코드
public PostWithViewCountResponse getPost(Long postId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다."));
post.increaseViewCount(); // viewCount++
return PostWithViewCountResponse.of(post);
}
▶ 예상했던 동작
1. findById(postId)를 통해 게시글을 조회한다.
2. post.increaseViewCount();를 실행하여 viewCount 값을 증가시킨다.
3.조회한 게시글을 PostWithViewCountResponse로 변환하여 반환한다.
4. DB에도 조회수가 증가한 상태로 저장되어야 한다.
▶ 실제 동작
- post.increaseViewCount();를 실행해도 viewCount 값이 1에서 멈춰 있고, 계속 증가하지 않음.
- DB에 UPDATE 쿼리가 실행되지 않음.
- 즉 viewCount 값이 애플리케이션에서는 증가하지만, DB에는 반영되지 않는 상태.
문제 원인 분석
1. JPA의 변경 감지는 트랜잭션 내에서만 동작한다.
JPA는 트랜잭션이 끝나는 시점(Commit 시점)에 영속성 컨텍스트(1차 캐시)에 있는 엔티티를 확인하고 변경된 내용이 있으면 UPDATE 쿼리를 실행한다.
즉 트랜잭션이 없으면 변경 감지가 동작하지 않기 때문에 UPDATE 쿼리도 실행되지 않는다.
▶ increaseViewCount()를 실행했지만, UPDATE가 실행되지 않은 이유
- findById(postId)로 가져온 post는 JPA가 관리하는 영속성 컨텍스트에 있음.
- 하지만 트랜잭션이 없으므로 트랜잭션이 끝날 타이밍이 없음.
- 결국 변경 감지가 동작할 기회를 얻지 못하고 viewCount 증가가 DB에 반영되지 않음.
해결 방법
@Transactional 적용
JPA의 변경 감지가 정상적으로 작동하려면 트랜재션이 있어야 한다.
따라서 @Transactional을 추가하여 트랜잭션 범위를 설정하면 문제를 해결할 수 있다.
▶ 수정된 코드
@Transactional // 추가
public PostWithViewCountResponse getPost(Long postId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다."));
post.increaseViewCount(); // 변경 감지 정상 동작
return PostWithViewCountResponse.of(post);
}
📌 트랜잭션이 적용된 후 변경 감지(Dirty Checking)가 정상적으로 동작하는 과정
1. 트랜잭션 시작 (@Transactional)
2. findById(postId) 실행 → 영속성 컨텍스트에 post 저장
3. post.increaseViewCount(); 실행 → viewCount 값 증가
4. 트랜잭션이 끝나면서 commit 실행 → JPA가 변경 감지 수행 → UPDATE 쿼리 실행
5. DB에 조회수 증가가 반영됨.
➡️ 오늘의 교훈 : 트랜잭션이 없는 경우 변경 사항이 반영되지 않는다. 트랜잭션을 올바르게 사용하자! 😁
'Back-End > JPA' 카테고리의 다른 글
| @Fetch(EAGER)와 fetch join 차이와 LAZY 로딩의 작동 방식 (0) | 2025.03.23 |
|---|---|
| Spring Data JPA : Auditing (1) | 2024.12.18 |
| Spring Data JPA : 벌크성 수정 쿼리와 엔티티 그래프 (2) | 2024.12.18 |
| Spring Data Jpa : 페이징과 정렬 (1) | 2024.12.18 |
| Spring DataJpa : 쿼리 메서드 기능 (0) | 2024.12.18 |