Blog

[Spring][258] 데이터베이스 및 애플리케이션 레벨에서의 동시성 문제 대응

Category
Author
Tags
PinOnMain
1 more property

1. 개요

동시성 문제를 해결하기 위한 다양한 방법들을 모두 적용해보며 JMeter로 테스트를 하고 최종적으로 결정한 방법을 선택한 과정을 정리하였습니다.

2. 동시성 해결 성능 테스트

책 나눔 신청에 대한 동시성 오류를 해결하기 위해 아래의 4가지 방법을 사용하였습니다.
1.
뮤텍스
2.
낙관적락
3.
비관적락
4.
@Transactional(isolation = Isolation.SERIALIZABLE)
4가지 방법 모두 동시성 오류가 성공적으로 해결이 되었고, 이에 대한 성능 테스트를 진행하였습니다.
테스트는 로컬에서 진행하였으며, Jmeter로 100개의 쓰레드에서 요청을 0.1초 안에 보내는 방식으로 여러 번 측정하여 평균값을 구하였습니다. 테스트 결과는 아래와 같습니다.
지연시간 평균값을 비교했을때 비관적락<낙관적락<Serializable<뮤텍스 순으로 성능이 좋았습니다.
비관적락이 낙관적락보다 성능이 더 좋게 나왔는데, 낙관적 락은 충돌이 많이 발생하지 않을 것이라 생각되는 부분에 사용하기 방법으로 100개의 요청 중 1개만 성공하는 위 테스트 상황에서는 낙관적 락이 비관적 락보다 낮은 성능을 보인 것으로 생각됩니다.

3. 동시성 오류 해결 방법 선택

뮤텍스는 위 4개 중 가장 성능이 좋지 않아 최종 선택지에서 제외하였습니다.
격리수준 Serializable은 성능이 두번째로 좋지 않기도 하고, 데드락 오류가 100건 중 약 10건 정도 발생하여 제외하였습니다.
남은 것은 비관적락, 낙관적락으로 프로젝트에는 책 대출, 책 나눔 신청 2가지에서 동시성 오류가 발생하는데 2가지에 다른 방법을 사용하였습니다.
1.
책 나눔 신청
책 나눔의 경우 특정 시간부터 시작되는 책 나눔 이벤트에 있는 책들을 클릭하여 선착순으로 가져가는 구조이며, 동시성 오류가 빈번하게 생길 것으로 보입니다. 따라서 낙관적락 보다는 충돌이 많이 발생하는 상황에서 쓰이는 비관적락을 최종 선택하였습니다.
2.
책 대출
책이 약 700만개가 있고 책이 대여상태인 경우에는 책을 예약할 수 있는 기능이 구현되어 있습니다. 따라서 책을 대여할 때 동시성으로 인한 충돌이 생길 확률이 낮아 낙관적 락이 더 적합하다 생각되나, 책나눔 신청에서 book 엔티티에 대해 비관적 락을 쓰기로 결정하였기에 동일하게 비관적락을 걸게 되었습니다.

참고 링크