Delivery

Mybatis batch처리 성능과 트랜잭션

2022. 8. 1. 17:19

 

이번글은 제가 우선순위 업데이트를 구현하는 과정에서 발생한 문제를 해결하는 글입니다.

 

문제상황

우선순위 업데이트를 할때 update문이 여러번 실행되는것입니다.

우선순위를 바꿀때 하나의 로우에서 우선순위 컬럼이 2로 변경된다면 이에따른 메뉴들의 우선순위가 다같이 변경되어야한다고 생각해서 구현을 한 상황에서 db호출이 여러번 진행되므로 db호출을 할때 connection을 맺고 그리고 쿼리를 실행하는 과정이 반복되기때문에 느려진다고 판단했습니다. 

프론트에서 받는데이터

[{id : 1, priority:3}, {id : 2, priority:1}, {id : 1, priority:4}, {id : 1, priority:5}] 프론트에서 저는 화면에 배치된 순서대로 받는다고 가정했습니다.

 

요구사항

하나의 connection에 쿼리를 여러번 실행해주는 방법이있으면좋겠다.

이에 따라 성능이 더 개선이 됬으면좋겠다.

 

해결방법

Mybatis의 foreach를 통해 배치처리를 하기때문에 DB connection한번에 여러번 쿼리를 실행수있게되었습니다.

저는 Mysql을 사용했습니다

코드는 아래와 같습니다

 

 

for문

데이터는 1000건을 넣었습니다.

서비스계층에서 for문을 통해 update를 호출하는경우는 아래와 같이 681~1266 ms 사이의 값이 나왔습니다.

 

배치처리 안사용한것

반면 mapper에서 batch처리를 한경우는 300대의 ms정도나오면 최소로 Time : 237 ms 정도 나왔습니다.

그렇다면 여기서 만약 데이터가 더 많아진다면 batch처리가 훨씬 빠르겠다 생각했습니다.

 

 

배치처리

그런데 여기서 고민이 생겼습니다 MenuGroup의 우선순위를 업데이트하는곳에서 사용되는데도 이렇게 많은 데이터가 들어가는 경우가 있을가? 그렇다면 for문이 빠르지 않을가 하고 저희가 구현하는 서비스를 현실적으로 생각해 개수를 낮춰보았습니다

📘10건의 경우는 
batch처리  - Time : 134
for문 - Time : 231

 

📗5건의 경우

batch처리  -  Time : 179

for문 - Time : 149 

 

건수가 낮아질수록은 for문이 더 빨라진다는것을 알았습니다. 그렇다면 배달의 민족앱에서 그룹을 몇개정도 만드는지 

조사해봤습니다. 제가 사는  주변 치킨집을 조사한결과 평균적으로 7개이며 떡볶이집은 10개 이상인 곳이 존재하기도했습니다.

그렇다면  업데이트건수가 적은경우로 맞춘 for문으로 만든다면 건수가 많아지면 차이가 확연히 벌어지기때문이며 추가적으로 저희가 추구하는 개발은 대용량 처리이기때문에 데이터 건수가 적더라도 속도 차이가 얼마 나지않는 batch처리를 선택했습니다.

여기서 보다시피 데이터 건수를 많이 추가할수록 batch처리를 이용하는것이 성능에 훨씬 도움이됩니다.

 

😅업데이트 추가적 문제

업데이트가 일부분만 이루어지는 부분이 존재하는 문제가 생길것이라고 생각됬습니다.

만약 이러한 문제가 발생한다면 정확한 우선순위대로 정렬되지 않는 문제입니다. 

bulk업데이트시에는 id가 존재하지않아도 업데이트가 빈곳으로 진행됩니다. 그렇다면 3개만 업데이트 되는경우가 존재하는데 이런경우를 막기위해서 앞부분에서 id가 모두다 존재하는지 파악하였습니다.
mybatis의 bulk업데이트는 좋지만 id존재하지않으면 SqlExcetpion을 보내주지않아서 조금 아쉬운점이있습니다.

그래서 이부분을 보완하기위해 size를 파악하여 업데이트 개수가 맞는지 1차적으로 파악해서 DB connection까지 가지않고 예외를 던져주는것입니다.

 

해결한 코드는 아래와 같습니다


더안전한 방법은 for문을 하나하나돌리면서 파악하는방법인데 이것은 너무 비효율적이라 생각합니다
꼭 안전성 측면에서는 그렇지만 업데이트가 안되는경우는 서비스에서 완전 큰일날 부분이아니라고 생각했고 성능이 느려져 오히려 서비스에서 문제가 생길것이라고 생각합니다.

'Delivery' 카테고리의 다른 글

레디스를 선택한 이유, 세션클러스터링  (0) 2022.08.05
레디스에 대해 알아보자  (0) 2022.08.05
테스트코드의 MockMvc utf-8 성능측정  (0) 2022.07.19
Mybatis ${}, #{} 차이  (0) 2022.07.17
피드백 반영 리펙토링 후기  (0) 2022.07.16
'Delivery' 카테고리의 다른 글
  • 레디스를 선택한 이유, 세션클러스터링
  • 레디스에 대해 알아보자
  • 테스트코드의 MockMvc utf-8 성능측정
  • Mybatis ${}, #{} 차이
cwangg897
cwangg897
cwangg897
wang's tech blog
cwangg897
전체
오늘
어제
  • 분류 전체보기 (43)
    • Kusinsa (1)
    • 자바 (0)
    • 스프링 (1)
    • 용어정리 (1)
    • Delivery (15)
    • Delivery - WIL (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • r

최근 댓글

최근 글

hELLO · Designed By 정상우.
cwangg897
Mybatis batch처리 성능과 트랜잭션
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.