Skip to content

Latest commit

 

History

History
34 lines (26 loc) · 2.11 KB

README.md

File metadata and controls

34 lines (26 loc) · 2.11 KB

재고 시스템으로 알아보는 동시성 이슈 해결하기

동시에 상품에 대한 주문을 요청한다면 일반적인 로직으로는 race condition의 발생으로 예상한 결과를 받을 수 없다.

애플리케이션에서의 해결

Synchronized

Synchronized는 여러 쓰레드에서의 접근을 막는다. 그러나 배포 서버는 통상 1대의 서버만을 두지 않는다. 다른 서버에서의 주문 요청은 막을 수가 없는 것이다.

데이터베이스 단에서 해결

  1. 낙관적 락
  2. 비관적 락
  3. Named Lock

낙관적 락

락을 걸지 않고 충돌이 일어났을때 해결한다. version 컬럼을 만들어 해결한다. version을 통해 정합성을 맞춘다. 충돌이 빈번하지 않다면 성능이 뛰어나다. 충돌이 일어났을 경우 프로그래머가 다시 요청하는 로직을 구성해야 한다.

비관적 락

타 트랜잭션이 특정 row의 lock을 얻는 것을 방지한다. 특정 row에 대한 update, delete를 할 수 없다. read는 가능하다.
충돌이 빈번하게 일어난다면 낙관적 락보다 성능이 좋을 수 있다. 락을 통해 업데이트를 제어하기에 데이터 정합성이 어느정도 보장된다.
락으로 인한 성능 저하는 있을 수 있다.

Named Lock

Lock 레포지토리를 만들어 관리해야 한다. 그렇기에 데이터소스에 연결하는 커넥션이 의도치 않게 증가하여 커넥션이 모자랄 수 있다. 따라서 실무에선 도메인 DB와는 분리된 데이터 소스를 사용하는 것을 권장한다.

레디스를 활용한 해결

  1. Lettuce - data-redis 패키지에 포함
  2. Redisson - 오픈 소스 라이브러리

Lettuce

구현이 간단하다. mysql의 NamedLock과 유사하지만 레디스를 활용하기에 커넥션 관리를 신경쓰지 않아도 된다.
스핀 락 방식이기 때문에 계속해서 락의 획득을 시도하려고 한다. 그렇기에 레디스에 그만큼의 부하가 전해진다

Redisson

락 획득 재시도를 기본 제공한다. pub-sub 방식이기 때문에 redis에 부하가 덜 간다.