Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

두 가지 동시성 문제와 Lock Trade-Off #243

Open
esperar opened this issue Mar 29, 2024 · 1 comment
Open

두 가지 동시성 문제와 Lock Trade-Off #243

esperar opened this issue Mar 29, 2024 · 1 comment

Comments

@esperar
Copy link
Contributor

esperar commented Mar 29, 2024

Describe

Problem

Hi를 운영하면서 두 가지의 동시성 문제가 발생할 수 있는 시나리오가 있습니다.

  1. 테이블 중복 예약 (하지만 거의 발생하지 않을 것 같음)
  2. 유저 중복 예약 (1, 2번 테이블에 동시에 유저가 올라가고 동시에 신청 버튼을 누르게 되면?)

Solution

1번 솔루션으로는 트랜잭션 격리 수준을 안전한 격리 수준으로 올려주어도 될 것 같으며, 혹은 redis 분산락 방식을 통하여 진행해볼 수 있을 것 같습니다. 현재 Hi가 CloudType에 배포되어있기도 하고 Redis를 사용중이기도 하니 단일 레디스 노드에 lock을 생성해 락 취득, 반납 로직을 애플리케이션 레벨에서 구현하면 괜찮을 것 같아요.

그럼 이 중에서 레디스 클라이언트 Redisson, Lettuce를 고려해볼 수 있을 것 같고 락 관련한 로직의 트래픽이 엄청나게 몰리지 않을 수도 있어서 스핀락 방식의 Lettuce를 사용해도 괜찮을 것 같아요. 사실 이미 스프링에서 관련 레디스 클라이언트 라이브러리가 많이 있어서 구현에 어렵지는 않을 것 같고 spring redis starter에 client는 redisson 방식이라 그냥 스타터팩에 있는거 사용해도 괜찮을 것 같아요

선택은 자유롭게 해주세요. Util 클래스를 만들어서 서비스로직에 다 구현하는 것 보다는 AOP 방식으로 커스텀 어노테이션을 생성해서 락이 필요한 서비스들에 어노테이션을 달아주면 좋겠습니다. 추가 인자로 TTL이나 Lock이름 락 시간관련 설정도 함께 추가해줘야해요


2번 솔루션으로는 일반적인 Pessimistic Lock을 통해서 userStatus를 추가하여 row에 락을 거는 방식입니다.
이를 통하여 테이블 전체에 거는 것이 아니기 떄문에 개별 로우 별로 lock을 걸어 안정성을 확보할 수 있습니다.

동시성이 발생하는 시나리오도 거의 평균적으로 같은 유저의 예약 요청 2개가 동시에 들어오거나 최악의 경우 거의 20개의 요청이 동시인데 이건 사실상 발생하지 않을거라고 확신할 수 있습니다.

Additional

Hi가 드디어 배포가 되다니

@esperar
Copy link
Contributor Author

esperar commented Mar 29, 2024

아 그리고 웹페이지에서의 따닥도 방지 해줘야할 것 같아요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant