낙관적 락, 비관적 락도 Rock이다.

영석·2025년 7월 9일

CS

목록 보기
3/3
post-thumbnail

💡 낙관적 락, 비관적 락이 필요한 이유

상품 재고가 한개 남았는데 동시에 구매요청이 들어온다면?

당연하게도 단 하나의 구매 요청만 처리가 되어야 하지만,
동시성 문제에 대한 대처가 되어있지 않다면 재고가 음수가 될 수도 있다.

이런 문제는 서비스 장애로 이어지거나, 데이터 정합성 마저 깨지게 된다.
그때마다 로깅하면서 에러를 추적할 것인가? 아니다 미리 방지해야 한다.

이제는 비즈니스 로직과 서비스 특성에 맞는 Lock 전략을 선택하고 적용해야 할 때이다.

🔒 낙관적 락 - Optimistic Lock

DB 업데이트의 횟수가 적으며, 충돌이 자주 발생하지 않을 것이라 가정하고
데이터 버전을 비교하여 충돌을 감지하는 Lock 메커니즘

낙관적 락 프로세스

낙관적 락은 충돌을 탐지하여 동시성 문제를 회피하거나 재시도하도록 한다.

낙관적 락은 기본적으로 충돌을 허용한다. 대신에 버전정보를 토대로 충돌을 탐지하는데

테이블에 version 정보를 담는 필드를 추가하고 매번 업데이트를 진행할때
version정보를 검증하는 식으로 충돌을 탐지한다.

즉, 처음 조회했을때 version정보가 도중에 변경되었다면 이는 충돌이라고 간주한다.

이후 재 조회를 하고 다시 UPDATE하는 로직과 별도의 검증로직을 통해
트랜잭션을 재실행 한다.

✅ 장점

1. 비관적 락 보다 성능상 이점있음

  • Lock을 선점하지 않기 때문에 병렬처리에 유리함

2. 데드락 발생 가능성 낮음

  • DB Layer에서 락을 선점하지 않기 때문에 트랜잭션간 교착상태 발생하지 않음

❌ 단점

1. 충돌 발생시 트랜잭션을 다시 시도하는 비용 발생

  • 충돌감지 + 데이터 재조회 + 재시도 로직필요함

2. 엔티티에 version을 관리하는 필드가 존재해야 함

  • 버전비교를 통한 충돌감지를 하려면 별도의 필드가 존재해야함

🔒 비관적 락 - Pessimistic Lock

DB 업데이트의 횟수가 많으며, 충돌이 자주 발생할 것이라 가정하고
데이터를 조회하는 순간부터 락을 걸어 접근을 방지하는 Lock 메커니즘

비관적 락 프로세스

비관적 락은 데이터에 동시 접근을 제한하여 충돌 가능성을 사전에 차단한다.

비관적 락은 DB 수준에서 Lock을 수행한다.
SELECT ... FOR UPDATE 같은 쿼리를 사용하여 Lock을 획득한 후
다른 트랜잭션의 데이터 접근을 방지하여 충돌 가능성을 차단한다.

이후 변경사항이 Commit 되었다면 Lock을 해제하여 대기 중인 다른 트랜잭션이 Lock을 획득하고 Update가 수행된다.

✅ 장점

1. 데이터정합성을 강하게 보장함

  • Lock을 걸어 다른 트랜잭션의 접근을 원천차단함

2. Race Condition 방지에 효과적임

  • 동시 접근하는 상황 자체를 제거하여 경쟁상태 방지함

3. 동시성이 높은 상황에서도 안정적

  • 충돌 가능성을 배제하여, 별도의 예외상황없이 안정적인 흐름 유지

❌ 단점

1. 트랜잭션 대기상태 발생으로 인한 성능 감소

  • Lock이 해제될때까지 다른 트랜잭션은 대기상태 -> 처리량 저하

2. 락으로 인한 데드락 발생 가능성 증가

  • 무분별한 순서로 다른 자원에 Lock을 걸면 교착상태 발생 가능함

3. DB 부하 증가

  • Lock 관리, 트랜잭션 대기처리에 대한 DB 리소스 사용함

🥑 결론

🚨 Lock 메커니즘, 서비스의 특징, 상황을 정확히 파악하고 타당한 근거하에 선택하자!

DB 업데이트가 적거나, 충돌이 발생할 가능성이 낮다고 생각하는 기능
(게시물 수정, 마이페이지 수정 등)은 낙관적 락이 좋은 선택지 일 수 있다

반대로 DB 업데이트가 많거나, 충돌이 발생할 가능성이 크다고 생각하는 기능
(물건 판매에 따른 재고감소, 티켓팅 등)은 비관적 락이 좋은 선택지이다.

따라서 단순히 성능, 구현 편의성으로 판단하기보다는 기능에 대한
트랜잭션의 특성과 정합성의 중요도를 종합적으로 판단하여 Lock 메커니즘을 선택해야 한다.

profile
느리게 갱신되는 개발실력 - >_0

0개의 댓글