Weekly I Learned/2023's(1. ~ 12.) WIL

2023년 11월 4주차(11/27 ~ 12/1) Weekly I Learned "Step by Step"

ikjo 2023. 12. 3. 22:29

지난 한 주 되돌아보기

나름대로 여유있었던 11월 3주차와 달리 이번 11월 4주차에 배정받았던 작업은 그간 관심갔던 부분인 동시성 이슈에 관한 것이었기에 하루하루 시간 가는 줄도 모르고 상당히 몰입도 있게 작업을 수행할 수 있었다. 🏃‍♂️

 

또 다른 기술적 과제가 주어지다!

지난 번 WebClient 를 활용하여 blocking I/O 처리 로직을 non-blocking I/O 로 전환하여 서버 성능 최적화 작업을 했던 이래로 새로운 기술적 과제를 배정받게 되었다. 최근에 동시성 이슈로 인해 Lost Update 가 발생하는 문제가 있었는데, 11월 4주차에는 동시성 이슈로 인한 문제를 개선하는 작업을 배정받게 되었다.

 

다소 긴 처리 시간을 요하는 트랜잭션 A 와 짧은 처리 시간을 요하지만 실시간으로 발생할 수 있는 트랜잭션 B 가 있었는데, 두 트랜잭션 모두 동일한 데이터를 조회하고 수정 처리했었기에, 충분히 동시성 이슈가 발생할 수 있었던 부분이었다. 그러나, 당초 코드에는 이러한 동시성 이슈에 대비한 Lock 등의 안전 장치가 부재한 실정이었다.

 

단순히, 한 트랜잭션이 커밋되거나 롤백될 때까지 해당 데이터를 읽지 못하도록 Lock 을 설정해놓는 것으로 끝낼 수도 있지만, 트랜잭션 A 의 경우 기존에 다소 긴 처리 시간을 요했기에, 동시성 이슈 발생 시 다른 트랜잭션에서는 해당 데이터 처리를 위해 다소 오랜 시간 기다려야 하는 문제점이 있었다. 이에, 트랜잭션 A 처리 성능을 최적화할 필요성이 있었다.

 

트랜잭션 A 의 경우 JPA 기반으로 데이터를 접근 및 처리하는 로직으로 구성되어있었는데, 살펴보면 N + 1 문제도 발생하고 있었을 뿐만 아니라, 대량의 데이터를 update 및 insert 함에 있어 단순히 단건 처리로 매번 MySQL 에 request 를 하는 문제도 있었다. 이에, distinct ~ fetch join 문을 통해 N + 1 문제를 처리하고 jdbcTemplate 기반으로 bulkUpdate 및 bulkInsert 처리함으로써 성능을 최적화시켰다. 이 과정에서 bulkUpdate 를 위한 여러가지 방법이 있다는 것을 배울 수 있어 유익했다.

 

되돌아 보면 신입 온보딩 당시에 트랜잭션 격리수준과 Lock 에 대해 나름대로 깊게 학습했었던 경험이 있었던 덕에, 이번 작업을 한결 수월하게 진행할 수 있었다. 그 과정에서 동기에게도 나의 지식과 경험을 공유할 수 있었다. 개인적으로는 해당 작업을 수행함에 있어 JPA 에 대해 한층 더 깊게 배울 수 있었던 것(JPA 동기화 전략 등)이 가장 큰 수확이었다. 🎁  아무쪼록, 로컬 환경에서는 상당히 유의미한 성능 개선이 이루어졌는데, 실제 운영 환경에서 얼만큼의 성능 개선이 이루어질지 기대가 된다. ⚡

 

(백준 1일 1커밋 운동은 계속되고 있다...🚀)