동시성 제어 기법 낙관적 락, 비관적 락

BlackHan·2024년 5월 24일
0

동시성

목록 보기
2/5

저번 시간에 동시성 제어의 배경과 하지 않았을 때의 문제점을 살펴보았다.
이번에는 동시성 제어 기법의 종류를 설명하고자 한다.

동시성 제어에는 Lock을 사용한 방법이 있다. 이번 시간에는 낙관적 락과 비관적 락에 대해서 알아본다.

낙관적 Lock

충돌하지 않을 것이라고 보고 진행한다.
그렇다면 어떻게 충돌을 방지할까?

방식

버전(Version)을 사용한다. 해당 데이터의 버전을 읽고, 데이터를 Commit하기 전에도 다시 버전을 읽는다.
이 두 버전이 일치할 때 비로소 Commit을 한다.

대략적 이미지는 아래와 같다.

이렇게 하면, 누군가가 동시에 데이터를 수정했을 때 먼저 수정한 사람의 Commit으로 인해 버전이 변경된다. 따라서 두 번째로 데이터를 수정하려는 사람은 처음 읽었을 때의 버전과 Commit 전에 읽은 버전이 달라진 것을 확인하고, 충돌이 발생할 뻔했다는 것을 인지하게 되어 롤백을 한다.

낙관적 락을 쓰는 경우

  • 충돌 가능성이 낮은 경우 - 데이터 수정이 드문 시스템에서 효과적이다. (읽는 작업이 많은 경우 ex 게시판)
  • 성능이 중요한 경우 - 충돌이 발생하지 않는다는 가정하에 트랜잭션을 유지할 필요가 없어 성능이 비관적 락보다 좋다.
  • 비동기 처리를 할 경우
    예를 들면 영화 티켓을 예매한다고 생각해보자.
  1. 클라이언트는 서버에 잔여석 정보를 요청한다.
  2. 클라이언트는 잔여석 정보를 받고, 정보를 입력하며 결제 준비를 한다. 이후 결제 요청
  3. 서버는 처음 버전과 결제 요청시 버전을 확인하기만 하면 된다.
    => 클라이언트가 데이터를 받고 수정 후 재전송 할 때까지 트랜잭션을 유지할 필요도 없고, 비동기적으로 처리할 수 있다. 이는 데드락을 피하는 데 유리하다.

낙관적 락의 단점

  • 실패시 롤백 처리가 복잡도가 올라간다.
  • 충돌이 일어난 경우 재시도를 해야 한다. 수정이 빈번하게 일어나는 시스템에서는 계속 버전이 변경될 수 있어, 재시도가 반복될 수 있다.

비관적 Lock

충돌할 걸 예상하고 락을 걸어서 진행하는 방식이다.
락을 걸고 데이터를 수정하는 동안, 다른 사용자는 자원을 이용할 수 없기에 대기를해야 한다.

여기에는 배타락(Exclusive lock)과 공유락(Shared lock)이 있다.

1. 배타 Lock

흔하게 생각해 볼 수 있는 방식으로, 한 트랜잭션이 진행되는동안 다른 트랜잭션이 접근을 못하게 Lock을 걸어둔다.
이는 전용 lock이라고도 하며, Lock이 걸리는 순간 다른 트랜잭션의 읽기와 쓰기는 불가능하다. Commit이 끝난 뒤 Lock이 풀리면 다음 트랜잭션이 권한을 가져간다.

2. 공용 Lock

read연산은 가능하고 write연산은 불가능 하게 끔 한다.
한 트랜잭션이 공유 락을 걸면 다른 트랜잭션도 동일한 데이터에 공유 락을 걸 수 있지만, 배타 락은 걸 수 없다.

우리가 여기서 알아야 할 점은 로킹 단위(Loking Granularity)이다.

로킹 단위(Loking Granularity)

즉 어떤 범위로 묶어서 Lock을 걸 것이냐 ? 라는 의미인데

크다 --------------------------------> 작다
데이터베이스, 릴레이션, 튜플, 속성 단위로 가능하다.

로킹 단위가 커질수록 구현이 쉽고 (그냥 대충 한번에 묶어버리면 되니깐_)
병행성 수준이 낮아진다. 때문에 로킹 오버헤드 감소

로킹 단위가 작아지면 병행성 수준이 높아져 여러 트랜잭션이 동시에 진행될 수 있지만, 관리가 어렵고 락 오버헤드가 증가

이렇게 종류를 알아보았다.
그렇다면 언제 낙관을 쓰고 언제 비관을 쓰는가?

비관적 락을 쓰는 경우

  • 수정하는 일이 빈번한 경우 - 낙관적 락의 단점을 처리할 수 있다.
  • 실시간으로 데이터를 처리해야 하는 시스템에서 사용
  • 데이터 무결성이 매우 중요한 경우 - 갱신 손실(Lost Update) 문제를 해결하여 데이터의 정합성을 유지한다.

비관적 락의 단점

  • 동시에 접근하는 트랜잭션이 많아지면 대기 시간이 늘어나고, 시스템 성능이 저하된다.
  • 락이 걸려 있는 동안 다른 트랜잭션이 대기해야 하므로 병행성이 떨어진다.

👋다음 시간에는 이로 인해 발생하는 데드락이 무엇인지 알아본다.👋

profile
Slow-starter

0개의 댓글