본문 바로가기
Develop/Spring

벌크 연산으로 인한 데이터 값 불일치 문제 해결하기

by jaeyoungb 2023. 8. 29.

📌 벌크 연산이란?

데이터베이스에서 대량의 데이터한 번에 처리하는 기술을 말한다.

 

📌 장점

- 성능 향상 : 대량의 데이터를 한 번에 처리하는 기술이기에, 데이터베이스와의 통신 횟수가 감소한다.

- 코드 간결성 : 복잡한 반복문과 데이터 조작 코드를 줄일 수 있다.

- 트랜잭션 최적화 : 트랜잭션 내에서 데이터 조작을 최적화할 수 있다. (데이터 일관성, DB 락 관리 측면에서 유리)

- 쿼리 최적화 : DB 내부적으로 쿼리를 최적화하는 기회를 제공한다. (효율적인 리소스 사용 가능)

 

📌  단점

- 메모리 사용 : 대량의 데이터를 메모리에 로드하고 처리하기 때문에, 메모리 사용량이 증가할 수 있다.

- 데이터 일관성 : 잘못된 벌크 연산을 구현하거나 트랜잭션 처리가 제대로 되지 않으면, 데이터 불일치 문제가 발생할 수 있다.

 

 


📌  문제 상황

게시글을 조회했을 때, 조회 수가 1 증가되도록 하는 로직을 Querydsl을 활용하여 JPQL을 작성

Querydsl을 활용하여 JPQL을 작성한 코드
Service Layer - 게시글 조회 및 조회수 증가 로직

 

게시글을 조회한 전체 로직을 실행한 결과는 다음과 같다.

 

H2 DB - 조회 수
응답 데이터

 

DB에 저장된 데이터와 응답되는 데이터 간의 불일치 문제가 발생한 것을 볼 수 있다.

 

 


📌 문제 파악

왜 이런 문제가 발생한 걸까?

바로 벌크 연산의 단점으로 꼽히는 데이터 불일치 문제였다.

 

일단, Querydsl를 통해서 JPQL을 작성하여 DB의 데이터 값을 변경하는 작업은 벌크 연산에 해당한다는 걸 알아야 한다.

그리고 벌크 연산은 영속성 컨텍스트를 우회하고, DB에 직접적으로 쿼리를 날려 처리한다.

 

보통 DB의 데이터 값을 변경하면 JPA의 변경감지(더티체킹) 매커니즘을 자주 사용하는데, 이 벌크연산은 그렇지 않다.

 

Service Layer - 게시글 조회 및 조회수 증가 로직

 

위 코드의 처리 과정을 살펴보자.

 

1. DB에서 조회된 Post 엔티티가 영속성 컨텍스트 내에 로드되고, 1차 캐시에 저장된다.

2. 벌크 연산을 통해 DB의 데이터를 변경한다. (조회 수 1 증가)

벌크 연산의 특성 때문에, 1차 캐시에 저장된 조회된 Post 객체의 데이터(조회 수)는 변경되지 않는다.

3. 1차 캐시에 저장된 변하지 않은 Post 객체가 반환된다.

 

이를 통해, DB의 데이터와 응답 데이터 간의 불일치 문제에 대한 원인을 파악할 수 있었다.

 

 


📌 문제 해결

'애초에, 조회 수 로직을 이렇게 짜야하나?'라는 의문이 드셨을 것이다.

맞다. 조회 수 증가 로직은 벌크 연산(Querydsl을 통해 JPQL을 작성하여 변경하는 로직)으로 구현할 이유가 없다.

대량의 데이터 처리도 아닌 단순 개별적인 엔티티 필드 값 변경이기 때문이다.

 

결국, JPA의 변경감지를 이용하는 방향으로 해결하였다.