비관적인 락 VS 낙관적인 락

dev-well-being·2023년 9월 1일
1

DB 충돌 상황을 개선할 수 있는 방법

  • database에 접근해서 데이터를 수정할 때 동시에 수정이 일어나 충돌이 일어날 수 있다. 이러한 상황을 해결하기 위해서는 두 가지 방법이 존재한다.
    • 첫번째, 테이블의 row에 접근시 Lock을 걸고 Lock이 걸려 있지 않을 경우에만 수정을 가능하게 할 수 있다.
    • 두번째, 수정할 때 내가 먼저 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것입니다.

비관적인 락(pessimistic lock)

  • 비관적 락이란 트랜잭션이 시작될 때 Shared Lock 또는 Exclusive Lock을 걸고 시작하는 방법이다.
  • Shared Lock을 걸게 되면 write를 하기 위해서는 Exclusive Lock을 얻어야 하는데 Shared Lock이 다른 트랜잭션에 의해서 걸려 있으면 해당 Lock을 얻지 못해서 업데이트 할 수 없다.
    • Transaction 1에서 table의 id 2번을 읽음 (name = Karol)
    • Transaction 2에서 table의 id 2번을 읽음 (name = Karol)
    • Transaction 2에서 table의 id 2번의 name을 Karol2로 변경 요청(name = Karol)
      • 하지만 Transaction 1에서 이미 shared Lock을 잡고 있기 때문에 Blocking
    • Transaction 1에서 트랜잭션 해제 (commit)
    • Blocking 되어 있었던 Transaction 2의 update 요청 정상 처리
  • 수정을 하기 위해서는 해당 트랜잭션을 제외한 모든 트랜잭션이 종료(commit) 되어야 한다.
    • 트랜잭션을 이용하여 충돌을 예방하는 것이 바로 비관적 락(Pessimistic Lock)입니다.

낙관적 락(optimistic lock)

  • 낙관적 락은 DB 충돌 상황을 개선할 수 있는 방법 중 2번째인 수정할 때 내가 먼저 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것이다.
  • DB에서 제공해주는 특징을 이용하는 것이 아닌 Application Level에서 잡아주는 Lock이다.
    • A가 table의 id 2번을 읽음 (name = Karol, version = 1)
    • B가 table의 id 2번을 읽음 (name = Karol, version = 1)
    • B가 table의 id 2번, version 1인 row의 값 갱신 (name = Karol2, version = 2) 성공
    • A가 table의 id 2번, version 1인 row의 값 갱신 (name = Karol1, version = 2) 실패
      • id 2번은 이미 version이 2로 업데이트 되었기 때문에 해당 row를 갱신하지 못함
  • 같은 row에서 대해서 각기 다른 2개의 수정 요청이 있었지만 1개가 업데이트 됨에 따라 version이 변경되었기 때문에 뒤의 수정 요청은 반영되지 않게 된다.
  • 낙관적 락은 version 등의 구분 컬럼을 이용하여 충돌을 예방합니다.

Rollback

  • 비관적인 락은 하나의 트랜잭션으로 묶여있기 때문에 수정이 하나 실패하면 database 단에서 전체 Rollback 일어나게 된다.
  • 낙관적인 락의 경우는 트랜잭션으로 잡히기 않기 때문에 수정을 못한 부분에 대해서는 롤백에 대한 책임을 Application 단에서 지며 Application에서 롤백을 수동으로 해줘야 합니다.

참고 자료

profile
안녕하세요!! 좋은 개발 문화를 위해 노력하는 dev-well-being 입니다.

0개의 댓글