# 동시성 제어
동시성 제어 방법들을 수치로 비교해서 선택하기 위해 부하테스트 도구를 활용했다.
### 부하테스트 도구 - Gatling
**선택 이유**
- 내가 가장 친숙한 자바 언어로 테스트코드 짜듯이 부하테스트를 작성할 수 있음
- 성능 테스트 후 HTML 리포트를 제공해줘서 성능 지표를 확인할 수 있음
- Gradle 내 플러그인으로 지원해서 프로젝트 내에서 버전 관리를 할 수 있음
### 비관적락
- 출돌이 발생할 확률이 높다고 가정하고 데이터에 액세스 하기 전에 먼저 락을 걸어 충돌을 예방하는 방식
- DB 트랜잭션을 이용해서 충돌을 예방하는 것
- 트랜잭션이 시작될 때 데이터베이스 레벨에서 shared lock 또는 exclusive lock을 걸고 시작하는 방법
- shared lock이 잡혀 있으면?
- a 트랜잭션에서 shared lock을 먼저 잡았다면 b 트랜잭션에서는 수정하지 못함
- a 트랜잭션이 종료(commit)되어야 b 트랜잭션에서 수정할 수 있음
- exclusive lock이 잡혀 있으면?
- a 트랜잭션에서 exclusive lock을 먼저 잡았다면 b 트랜잭션이서는 읽지도 못함
- a 트랜잭션이 종료(commit)되어야 b 트랜잭션에서 읽을 수 있음
#### 장점
- 충돌 발생을 사전에 방지하고 데이터 일관성 유지
#### 단점
- 동시 처리 성능 및 교착상태 발생 가능성
### 낙관적락
- 충돌이 거의 발생하지 않을 거라고 가정하고 충돌이 발생한 경우에 대비하는 방식
- DB가 제공하는 락 기능을 사용하지 않고 애플리케이션 레벨에서 잡아주는 lock이고 version과 같은 구분 칼럼을 이용해서 충돌을 예방한다
- 데이터베이스 레벨에서의 롤백이 없기 떄문에 충돌 시 대처 방안 구현해야 함
#### 장점
- 리소스 경쟁이 적고 락으로 인한 성능 저하가 적다
#### 단점
- 충돌 발생 시 처리해야 할 외부 요인 존재
## 이커머스 프로젝트에서 발생하는 동시성 이슈
### 포인트 충전
포인트 충전의 경우 하나의 유저가 흔히 말하는 '따딱' 이슈가 발생할 수 있다. 포인트 충전은 돈과 관련되어 있는 비즈니스 상으로 아주 예민하다. 그러나 충돌 발생이 하나의 유저에서 발생하고 다른 유저와의 충돌은 발생하지 않기 떄문에 충돌 발생이 많지 않다. 따라서 데이터베이스에 부담을 주기보단 애플리케이션 레벨에서 해결하는 낙관적락을 사용한다.
### 주문
주문은 하나의 유저가 아닌 다른 유저와의 충돌도 고려해야 한다. 그리고 이커머스 도메인에서 주문은 핵심 로직으로 동시성에 제대로 보장되어야 한다. 따라서 비관적락을 사용한다.
....