상품 재고가 한개 남았는데 동시에 구매요청이 들어온다면?
당연하게도 단 하나의 구매 요청만 처리가 되어야 하지만,
동시성 문제에 대한 대처가 되어있지 않다면 재고가 음수가 될 수도 있다.
이런 문제는 서비스 장애로 이어지거나, 데이터 정합성 마저 깨지게 된다.
그때마다 로깅하면서 에러를 추적할 것인가? 아니다 미리 방지해야 한다.
이제는 비즈니스 로직과 서비스 특성에 맞는 Lock 전략을 선택하고 적용해야 할 때이다.
DB 업데이트의 횟수가 적으며, 충돌이 자주 발생하지 않을 것이라 가정하고
데이터 버전을 비교하여 충돌을 감지하는 Lock 메커니즘

낙관적 락은 충돌을 탐지하여 동시성 문제를 회피하거나 재시도하도록 한다.
낙관적 락은 기본적으로 충돌을 허용한다. 대신에 버전정보를 토대로 충돌을 탐지하는데
테이블에 version 정보를 담는 필드를 추가하고 매번 업데이트를 진행할때
version정보를 검증하는 식으로 충돌을 탐지한다.
즉, 처음 조회했을때 version정보가 도중에 변경되었다면 이는 충돌이라고 간주한다.
이후 재 조회를 하고 다시 UPDATE하는 로직과 별도의 검증로직을 통해
트랜잭션을 재실행 한다.
DB 업데이트의 횟수가 많으며, 충돌이 자주 발생할 것이라 가정하고
데이터를 조회하는 순간부터 락을 걸어 접근을 방지하는 Lock 메커니즘

비관적 락은 데이터에 동시 접근을 제한하여 충돌 가능성을 사전에 차단한다.
비관적 락은 DB 수준에서 Lock을 수행한다.
SELECT ... FOR UPDATE 같은 쿼리를 사용하여 Lock을 획득한 후
다른 트랜잭션의 데이터 접근을 방지하여 충돌 가능성을 차단한다.
이후 변경사항이 Commit 되었다면 Lock을 해제하여 대기 중인 다른 트랜잭션이 Lock을 획득하고 Update가 수행된다.
DB 업데이트가 적거나, 충돌이 발생할 가능성이 낮다고 생각하는 기능
(게시물 수정, 마이페이지 수정 등)은 낙관적 락이 좋은 선택지 일 수 있다
반대로 DB 업데이트가 많거나, 충돌이 발생할 가능성이 크다고 생각하는 기능
(물건 판매에 따른 재고감소, 티켓팅 등)은 비관적 락이 좋은 선택지이다.
따라서 단순히 성능, 구현 편의성으로 판단하기보다는 기능에 대한
트랜잭션의 특성과 정합성의 중요도를 종합적으로 판단하여 Lock 메커니즘을 선택해야 한다.