본문 바로가기
Research/Database

DB_Optimistic Lock vs. Pessimistic Lock

by RIEM 2023. 2. 24.

Optimistic Lock(낙관적 락)과 Pessimistic Lock(비관적 락)에 대해 알아보도록 하자.

DB 충돌 상황을 개선하는 방법

여러 유저가 동시에 데이터를 수정하게 되면 DB에서 충돌이 발생한다. 이를 방지하기 위해 우리는 2가지 접근 방법으로 개선할 수 있다.

  1. 테이블에 row 접근하면 Lock을 걸어 다른 이들의 접근을 막는다. Lock이 풀렸을 때만 다시 수정을 할 수 있게 한다
  2. 수정 시 내가 먼저 이 값을 수정했다고 명시해서 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것이다

데이터 락의 유형

데이터베이스에는 데이터를 lock거는데 2가지 모델이 있댜.

  1. 낙관적 락(Optimistic locking)
  2. 비관적 락(Pessimistic locking)

낙관적 락(Optimistic Lock)

낙관적 락이란?
낙관적 락은 낙관적 동시성 제어라고도 불리는데, 이는 라킹을 사용하지 않는 관계형 DB에서 사용되는 동시성 제어 기술을 말한다. 낙관적 락을 사용하면 여러 유저가 같은 기록을 수정하려고 시도할 때, 유저들보고 이 데이터는 다른 사람들이 수정중인 데이터입니다라고 알려주지 않아도 된다. 앱 관점에서 보면 제출될 때만 데이터의 수정을 허용한다는 말이다. 만약 한 유저가 데이터를 수정을 완료했고, 그 같은 데이터를 동시에 수정하려는 다른 유저가 있다면 그들에게 충돌이 생겼다고 알려준다.

기술 관점
데이터를 수정할 때 먼저 온 사람이 이 데이터를 수정하겠다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 만드는 것이다. 다만 이는 DB 제공 특징이라기 보다는 Application 단에서 lock을 수행해주는 것이다.

핵심은 version 등 구분 컬럼을 이용하여 충돌을 예방하는 방법이다

Screen Shot 2023-02-24 at 1 11 22 AM
자료 참조 https://sabarada.tistory.com/175

절차로 한번 보자.

  1. 먼저 온 T1(Transation1)이 Id 2번 데이터(sujan)을 읽는다(version 1)
  2. 뒤에 온 T2가 같은 데이터(sujan)을 읽는다(version 1)
  3. 뒤에 온 T2가 약삭빠르게 먼저 데이터를 sujan -> jade로 update 해버린다(version 1 -> 2)
  4. 이후 느림보 T1가 같은 데이터인 sujan을 simpson으로 update 요청을 했지만 T1은 과거의 버전으로 요청을 했기에 실패한다(version 1)

장점
행동 결과에 대한 데이터를 락거는데 생기는 간접 소요 시간인 오버헤드를 줄일 수 있다. 동시 업데이가 없으면, 이 낙관적 락은 빠르게 업데이트해준다.

언제 사용하나?

  • 동시 기록 업데이트가 그다지 자주 발생하지 않거나 또는 라킹 오버헤드가 높을 때

비관적 락(Pessimistic Lock)

비관적 락이란?
한 기록을 동시에 업데이트 하는것을 방지하는 기술이다. 유저가 한 데이터를 수정하기 시작하면 락이 걸린다. 이 데이터를 수정하려는 다른 유저들은 '누가 이 데이터를 수정하고 있으니 건들지 마시오'라는 안내를 받는다. 늦게 온 다른 유저들은 첫 유저가 수정을 마칠 때까지 기다려야 한다. 수정을 마치면 비로소 락이 풀린다.

비관적 락은 충돌을 줄일 수 있게 해준다는 점이다. 수정은 serialized된다.

기술적 관점
비관적 락은 트랜잭션이 시작될 때 Shared Lock(Exclusive Lock)을 걸고 시작하는 것이다. 추후 다른 유저가 write를 시도하려하는데, Exclusive Lock이 이미 먼저온 유저의 트랜잭션에 잡혀있기에 늦게온 유저는 업데이트를 할 수 없다.

Screen Shot 2023-02-24 at 1 02 42 AM
자료 참조 https://sabarada.tistory.com/175

절차로 한번 파악해보자.

  1. 먼저 온 T1(Transaction 1)이 table의 Id의 2번 데이터(sujan)를 읽기 시작한다
  2. 뒤에 온 T2이 같은 데이터인 2번 데이터(sujan)을 읽는다
  3. 뒤에 온 T2이 2번 데이터를 sujan에서 jade로 업데이트 해달라고 요청한다. -> 하지만 T1이 이미 shared lock을 가지고 있기 때문에 DB가 이 요청을 블락한다 -> 할 수 없이 T2는 대기한다..
  4. T1이 볼일을 다 보고 트랜젝션을 해제(commit) 한다
  5. 블락이 풀리면서 T2의 update 요청이 정상 처리된다

비관적 락은 이전 업데이트가 끝날 때까지 딜레이되어도 되는 작업에 적합하다. 인터벌이 짧은 업데이트에 적용하면 좋다.

롤백(Rollback)

만약 업데이트 하는 테이블이 1개가 아니라 2개 이상이면 어떻게 될까? 2번째 테이블을 수정하는 도중에 충돌이 발생한 경우 롤백을 수행해야 한다. 비관적 락과 낙관적 락의 롤백 방식은 다르다고 한다. 상세한 내용은 이 블로그를 참조하면 되겠다.
https://sabarada.tistory.com/175

낙관적 락 vs. 비관적 락

낙관적 락(Optimistic Lock)

  • 성능이 더 좋다. 트랜잭션이 필요없기 때문
  • 충돌이 잘 일어나지 않는 부분에 사용하면 좋다. 충돌 발생 시 롤백을 개발자가 처리해줘야 하고 비용도 크다.

비관적 락(Pessimistic Lock)

  • 롤백이 더 편하다. 낙관적 락은 롤백을 개발자가 직접 처리해주어야 하지만, 비관적 락은 트랜잭션만 롤백하면 된다.
  • 충돌이 많이 예상되거나 또는 충돌 시 비용이 클 것으로 예상되는 부분에 사용하면 좋다

참조

'Research > Database' 카테고리의 다른 글

DB_Redis 설치 및 명령어 Cheatsheet(Mac OS)  (0) 2023.02.27
DB의 인덱스란  (0) 2023.02.26
TypeORM_QueryBuilder_Select  (0) 2023.02.24
DB_ODM vs. ORM  (0) 2023.02.23
mongoDB_userNewUrlParser, userUnifiedTopology 옵션은 무엇인가?  (0) 2023.02.06

댓글