Today I Learned
조회수 vs 좋아요: 동시성 처리 전략 비교와 설계 고민
지난 프로젝트에서 좋아요 기능의 동시성 문제를 낙관적 락으로 해결한 경험이 있다. 당시에는 사용자마다 좋아요 상태를 정확히 관리해야 했기 때문에 낙관적 락이 적합하다고 판단했다. 그런데 이번에는 조회수 증가 로직을 설계하면서, 좋아요처럼 낙관적 락을 써야 하나? 라는 의문이 들었고, 두 기능의 성격 차이를 고민하게 되어 이렇게 정리해본다.
조회수와 좋아요의 기능적 차이
| 항목 | 조회수 | 좋아요 |
| 성격 | 단순 접근 | 명시적 클릭 |
| 취소 가능성 | 없음 | 있음 |
| 정확성 요구 | 대략적인 누적이면 충분 | 누가 눌렀고 정확한 누적 숫자 파악 필요 |
| 중복 허용 | 허용 | 제한 |
조회수는 "얼마나 많은 사람이 봤는가"를 누적하는 지표이고, 좋아요는 "누가 좋아했는가"를 기록하는 지표이다. 따라서 조회수는 대략적인 누적만 보장되면 되지만, 좋아요는 정확한 상태 관리와 중복 방지가 필요하다.
좋아요: 낙관적 락(Optimistic Locking)이 적합한 이유
좋아요 기능은 다음과 같은 이유로 낙관적 락을 적용하는 것이 효과적이다.
- 사용자가 좋아요를 눌렀는지를 정확히 파악해야함
- 좋아요 취소가 가능함
- 중복 클릭 방지가 필요함
- 정확한 상태 동기화가 중요함
@Version 필드를 가진 엔티티에 대해 좋아요 상태를 변경할 때, 버전 충돌을 감지하고 재시도하는 방식으로 동시성 문제를 해결할 수 있다.
조회수: JPQL 직접 증가 방식이 적합한 이유
조회수는 단순히 숫자를 누적하는 기능이기 때문에, 다음과 같은 방식이 더 적합하다.
@Modifying
@Query("UPDATE Match m SET m.viewCount = m.viewCount + 1 WHERE m.id = :id")
void incrementViewCount(@Param("id") Long id);
- DB에서 직접 증가시키므로 동시성 문제 없음
- JPA의 변경 감지와 무관하게 동작함
- 성능이 뛰어나고 안정적임
조회수는 "정확한 1회 증가"보다 "대략적인 누적"이 중요하기 때문에, 낙관적 락을 적용하면 오히려 성능 저하와 충돌 문제가 발생할 수 있다.
결론
조회수와 좋아요는 비슷해 보이지만, 동시성 처리 전략은 완전히 다름을 알 수 있었다.
- 좋아요는 정확성과 사용자 상태 관리가 중요하므로 낙관적 락이 적합
- 조회수는 누적성과 성능이 중요하므로 JPQL 직접 증가 방식이 적합
기능의 성격을 이해하고 그에 맞는 전략을 선택하는 것이 좋은 설계의 방향임을 배웠다.