-
아래는 재고시스템으로 알아보는 동시성이슈 해결방법 강의를 정리한 내용입니다.
실제 강의에서는 예시를 통해 설명하고 있어 강의를 보는 것을 추천합니다.레이스컨디션이란
두 개 이상의 프로세스가 공통 자원을 읽거나 쓸 때,
접근 순서에 따라 실행결과가 달라지는 상황을 레이스 컨디션이라 한다.
= 데이터의 안정성과 신뢰성을 보장할 수 없다.
Synchronized 이용해 보기
- 자바에서는 synchronized를 사용해서 하나의 스레드만 접근 가능하도록 할 수 있다.
- 메서드에서 사용 또는 객체 변수에 사용
- Sychronized는 하나의 프로세스 안에서만 보장이 된다.
결론적으로 서버가 1대일 때에는 괜찮겠지만 여러 대가 되면 사용할 수 없음(운영에선 거의 사용되지 않음)
Database 이용해 보기
1. Pessimistic Lock
- 실제로 데이터에 락을 걸어서 정합성을 맞춰주는 방법
- exclusive lock 걸리면 락 해제되기 전까지는 다른 스레드에서 접근 불가
- 쿼리문 + for update로 알 수 있음
- 충돌이 빈번하게 일어난다면 Optimistic Lock보다 성능 좋을 수 있음
- 락을 통해 제어하므로 정합성 어느 정도 보장된다는 장점,
- 단점으로는 별도의 락을 잡으므로 성능감소가 있을 수 있다는 점
2. Optimistic Lock- 락 이용하지 않고 버전 이용해서 정합성 맞추는 방법
- 같은 버전에 업데이트 2개가 들어왔을 때, 앞사람이 바꾸고 버전 올려버리면 뒷사람은 바꾸지 못하는 식
- 장점은 별도의 락을 잡지 않으므로 pessimistic lock보다 성능상 이점이 있음
- 단점으로는 업데이트 실패 시 재시도 로직을 개발자가 만들어 주어야 함
- 충돌이 빈번하게 일어날 확률이 높다면 pessimistic lock사용하는 것을 권장
3. Named Lock- 이름을 가진 메타데이터 락
- 이름을 가진 락을 획득 후 해제 될 때까지 다른 세션은 락 획득 못함
- 트랜젝션 종료될 때 자동으로 락이 해제되지 않으므로 별도의 명령어 사용하거나 선점 시간 끝나야 해제됨
Redis 이용해 보기
1. Lettuce
- spin Lock은 락 획득하려는 스래드가 획득가능한지 계속 확인하면서 획득하는 방식
- mysql의 네임드락이랑 비슷함
- 다른 점은 레디스 활용한다는 점이랑 세션관리에 신경 쓰지 않아도 된다는 점
- key로 setnx 하여 락을 획득하고 완료 시 키를 삭제하여 락을 해제해 주는 방식
- 구현이 간단하다는 장점
- 단점은 스핀락 방식이므로 레디스에 부하를 줄 수 있음
- 때문에 Thread.sleep을 통해서 락 획득기간에 텀을 주어야 함
2. Redisson- 레디슨은 자신이 점유하고 있는 락을 해제할 때, 채널에 메시지를 보내줌으로 써 락 획득을 하라고 알려주몬 락 획득 시도함
- 락 관련한 클래스 제공함
- pub-sub : 채널을 하나 만들고 락을 점유 중인 스레드가 획득 대기 중인 스레드에게 해제를 알려주면 그때 시도하는 방식
- 별개의 리트라이 로직을 작성하지 않아도 됨
# 인프런 강의 추천 (내돈내산)
[ 재고시스템으로 알아보는 동시성이슈 해결방법 ]
결론
어떤 데이터를 업데이트하는 로직을 생성했을 때 알아서 한 번에 하나의 스레드만 접근할 거라는 행복한 상상을 해서는 안된다.
줄을 세워서 순차적으로 접근할 수 있도록 처리해주어야 한다.
아니면 다른 방법이라도.. 🤔'자바_스프링' 카테고리의 다른 글
Spring Rest Docs 맛보기 (0) 2023.04.04 spring boot 2.7.x에서의 swagger와 redisson 충돌 (0) 2023.03.15 Collection 및 Map인터페이스 간단요약 (0) 2023.02.17 TDD연습하기(2) (자바 플레이그라운드 with TDD, 클린 코드) (0) 2023.02.16 TDD연습하기(1) (자바 플레이그라운드 with TDD, 클린 코드) (0) 2023.02.16 댓글