본문 바로가기
CS/데이터베이스

동시성 제어하기 - 02. 쓰기락과 읽기락 - 이론

by 컴쏘 2023. 6. 7.
728x90

동시성 제어를 위한 가장 보편적인 방법은 락을 통한 줄세우기

쓰기락과 읽기락

락을 통해 동시성을 제어할 때는, 락의 범위를 최소화 하는 것이 중요

→ 락을 잡는동안 수행하는 작업의 범위를 최소화 하는 것

  • 락의 범위가 크면 클수록 락을 획득하기 위한 여러 트랜잭션들이 대기하는 시간이 길어짐 → 그만큼 성능도 내려간다.
  • 락의 범위가 길어질수록 Connection Pool을 점유하는 시간이 길어짐 → 최악의 경우에는 Connection Pool 고갈로 이어질 수 있음

MySQL에서는 트랜잭션의 커밋 혹은 롤백시점에 잠금이 풀림 → 트랜잭션이 곧 락의 범위

  • 따라서 여기서는 락의 범위를 최소화 한다는 것은 하나의 트랜잭션을 최소화 한다는 것임
  • 예시) 만약 S3이미지를 업로드 한다고 했을 때 이것이 트랜잭션 범위안에 들어가게 된다면, S3 네트워크 상태에 따라서 트랜잭션이 굉장히 길어질 수 있음 → 이런 경우에는 외부 네트워크 의존성이나 외부 I/O 가 발생하는 것들은 가능하면 최대한 트랜잭션 범위 밖에서 해주는 것이 좋음

MySQL에서는 쓰기락, 읽기락 두 가지 잠금을 제공

  • 읽기락이 잠금을 획득한 상태에서 다른 읽기락이 들어온다면, 읽기락끼리는 잠금 공유가 가능 (대기 없이 데이터 읽기 가능)
    • 읽기락 : SELECT … FOR SHARE
  • 쓰기락은 잠금 획득(데이터를 점유하고 있는 상태)을 하면 어떤 것이 들어와도 무조건 대기가 발생
    • 쓰기락 : SELECT … FOR UPDATE 또는 UPDATE, DELETE 쿼리

하지만, 매번 잠금이 발생할 경우, 성능저하를 피할 수 없음 → MySQL에서 일반 SELECT(FOR SHARE 혹은 FOR UPDATE 또는 UPDATE, DELETE 가 없는 SELECT)는 nonblocking consistent read로 동작(대기 없는 동작)

이것이 가능한 이유는 Undo Log를 통해서 원본 데이터를 변경했을 때, 커밋이 되기 전에 데이터를 계속 관리하고 있기 때문에 가능한 것

레코드 락

MySQL에서 잠금은 row가 아니라 인덱스를 잠근다. → 인덱스가 없는 조건으로 Locking Read시 불필요한 데이터들이 잠길 수 있음

  • 락을 잡을 때도 인덱스에 따라서 락의 범위가 달라지기 때문에 인덱스 설정이 매우 중요하다.

추가로 공부해볼만 한 것들

  • Java에서의 동시성 이슈 제어방법
  • 분산 환경에서의 동시성 이슈 제어방법
  • MySQL의 넥스트 키락이 등장한 배경
  • MySQL 외래키로 인한 잠금
  • MySQL 데드락

2023 KAKAO Tech Campus_BackEnd 필수 과정
DB(MySQL) 강의 정리 내용입니다.
728x90