database

낙관적 락(Optimistic Lock)

낙관적 락 (Optimistic Lock)은 데이터 갱신 시 충돌이 발생했는지 검증하고, 충돌이 없을 때만 갱신을 허용하는 방식을 의미합니다. 따라서 충돌이 많이 일어나지 않는 환경에서 많이 사용되며, 비관적 락보다는 성능이 좋습니다.


낙관적 락은 자원의 경쟁을 낙관적으로 바라봅니다. 따라서 다중 트랜잭션이 동시에 데이터를 수정하지 않는다고 가정합니다. 읽은 시점에서는 상관없지만, 데이터를 수정하는 시점에서는 앞에서 읽은 데이터가 다른 사용자에 의해 변경이 되었는지 검사를 해야합니다.

동시성 이슈

온라인 쇼핑몰에서 아래의 요구사항이 있다고 가정해 보겠습니다.


- 상품 H의 재고 수 : 10
- 사용자 A와 사용자 B가 동시에 상품 H를 구매

사용 시나리오는 아래와 같습니다.


  1. 사용자 A는 상품 H의 재고를 조회합니다.
  2. 사용자 B도 같은 시점에 상품 H의 재고를 조회합니다.
  3. 사용자 A는 상품 H를 2개 구입하고, 사용자 B는 상품 H를 6개 구입합니다.

위 case인 경우에 낙관적 락 사용전과 후를 확인해 보고 낙관적 락에 대한 이해도를 높여 봅시다.


📖 낙관적 락 사용 전


- 사용자 A는 재고를 8( 10 - 2 )로 업데이트 합니다.
- 사용자 B는 재고를 4( 10 - 6 )로 업데이트 합니다.

사용자 B가 마지막 업데이트를 했다고 한다면, 재고는 4로 업데이트 됩니다. 하지만 실제로는 2개가 남아야 합니다. 이는 동시성 문제로 인해 데이터가 불일치하게 됩니다.

📖 낙관적 락 사용 후


낙관적 락 (Optimistic Lock)은 주로 version 필드나 타임스팸프 기반의 필드를 사요하여 동시성 충돌을 확인합니다.


  1. products 테이블에 version 열을 추가합니다. 초기 상태의 상품 H의 version 값은 1입니다.
  2. 사용자 A가 재고 업데이트 시 version 1인 경우도 AND로 추가하여 업데이트 쿼리를 실행합니다. 이 때 version은 2로 함께 변경합니다.
  3. 사용자 B가 재고를 업데이트 시도를 합니다. 이떄 version 1인 경우를 AND로 찾습니다. 하지만, version 1은 존재하지 않기 때문에 업데이트에 실패합니다.
  4. 사용자 B는 실패한 작업에 대한 상품 H에 대한 조회를 다시 진행하여 작업을 재시도 하게 됩니다.

정리

낙관적 락(Optimistic Lock)을 통해 동시성 이슈를 방지하고 데이터 무결성을 유지할 수 있습니다. 이는 데이터 충돌이 빈번하지 않는 시스템에 적합합니다.


Word

Deadlock

데드락(Deadlock)이란, 두 개 이상의 작업이 서로 자원을 점유한 상태에서 상대방의 자원을 기다리며 영원히 진행되지 못하는 상태를 말합니다.

Embedding Pattern
 - 스레드 1 : A 정보를 구하고 잠금
 - 스레드 2 : B 정보를 구하고 잠금
 - 스레드 1 : B 정보를 구할 블로킹
 - 스레드 2 : A 정보를 구할 블로킹

Dirty Read

특정 트랜잭션에 처리가 완료되지 않은 데이터를 다른 트랜잭션에서 확인 할 수 있는 현상을 의미합니다. dirty read를 허용하게 되면, 데이터가 나타났다가, 사라졌다가 하는 현상을 초래하기 때문에 정합성 문제가 발생합니다.

Non-Repeatable Read

하나의 트랜잭션에서 동일한 Select 쿼리를 실행 시 다른 결과가 표출되는 현상으로, 결제와 같은 중요한 데이터를 다룰 시에 큰 문제를 발생 시킬 수 있습니다.

Phantom Read

하나의 트랜잭션에서 없던 데이터가 생기는 현상을 말합니다.


참고 링크