동시에 상품에 대한 주문을 요청한다면 일반적인 로직으로는 race condition의 발생으로 예상한 결과를 받을 수 없다.
Synchronized는 여러 쓰레드에서의 접근을 막는다. 그러나 배포 서버는 통상 1대의 서버만을 두지 않는다. 다른 서버에서의 주문 요청은 막을 수가 없는 것이다.
- 낙관적 락
- 비관적 락
- Named Lock
락을 걸지 않고 충돌이 일어났을때 해결한다. version 컬럼을 만들어 해결한다. version을 통해 정합성을 맞춘다. 충돌이 빈번하지 않다면 성능이 뛰어나다. 충돌이 일어났을 경우 프로그래머가 다시 요청하는 로직을 구성해야 한다.
타 트랜잭션이 특정 row의 lock을 얻는 것을 방지한다. 특정 row에 대한 update, delete를 할 수 없다. read는 가능하다.
충돌이 빈번하게 일어난다면 낙관적 락보다 성능이 좋을 수 있다. 락을 통해 업데이트를 제어하기에 데이터 정합성이 어느정도 보장된다.
락으로 인한 성능 저하는 있을 수 있다.
Lock 레포지토리를 만들어 관리해야 한다. 그렇기에 데이터소스에 연결하는 커넥션이 의도치 않게 증가하여 커넥션이 모자랄 수 있다. 따라서 실무에선 도메인 DB와는 분리된 데이터 소스를 사용하는 것을 권장한다.
- Lettuce - data-redis 패키지에 포함
- Redisson - 오픈 소스 라이브러리
구현이 간단하다. mysql의 NamedLock과 유사하지만 레디스를 활용하기에 커넥션 관리를 신경쓰지 않아도 된다.
스핀 락 방식이기 때문에 계속해서 락의 획득을 시도하려고 한다. 그렇기에 레디스에 그만큼의 부하가 전해진다
락 획득 재시도를 기본 제공한다. pub-sub 방식이기 때문에 redis에 부하가 덜 간다.