[DB] 동시성 제어를 위한 Lock + Named Lock

soohee·2023년 2월 25일
1

Database

목록 보기
1/3
post-thumbnail

Lock이란?

lock이란 트랜잭션 처리의 순서를 보장해서 동시성을 제어하기 위한 방법입니다.

Lock의 종류

공유락 (Read Lock)

데이터를 읽을 때 사용되어지는 Lock. 공유 Lock끼리는 동시에 접근이 가능하다.
즉, 하나의 데이터를 읽는 것은 여러 사용자가 가능하다는 것이다.
그러나, 공유 Lock이 설정된 데이터에 베타 Lock을 사용할 수는 없다.

베타락 (Write Lock)

데이터를 변경하고자 할 때 쓰이는 Lock. 베타 Lock을 해제될 때까지 다른 트랜잭션은 해당 리소스를 접근할 수 없다.

Lock의 설정 범위

DB(데이터 베이스)

데이터 베이스 레벨에서 lock을 하는 것이다.
하나의 세션만 DB의 데이터에 접근이 가능하다. 일반적으로는 사용하지 않고, 만약 DB의 소프트웨어 버전을 올리거나 할 때만 제한적으로 사용한다.

파일

데이터 베이스 파일을 기준으로 lock을 설정하는 것이다.

테이블

테이블 수준에서 Lock을 거는 것으로, 모든 행을 업데이트 하거나 전체 테이블에 영향을 주는 변경을 할 때 테이블 수준에서 lock을 건다. 주로, DDL 구문과 함께 사용되며 DDL Lock이라고도 부른다.

컬럼

컬럼 기준으로 Lock을 설정한다. 그러나 컬럼 기준으로 설정하는 것은 리소스가 많이 들기 때문에 거의 사용되지 않는다.

주로 행 수준 Lock을 제일 많이 사용하며, 1개의 행을 기준으로 Lock을 설정한다.
DML Lock이라고도 부른다.

프로젝트에서 Named Lock을 사용하다.

프로젝트에서는 분산락을 구현하기 위해 Named Lock을 사용했다. Redis를 사용할까 싶었지만 또 다른 인프라 구축 비용이라던지 유지보수 비용이 들어갈 것이라고 판단하여, MySQL이 제공하는 Named Lock을 사용하였다.

NamedLock은 고유한 이름으로 식별되는 잠금이며, 잠금을 획득해 공유 자원 접근을 동기화할 수 있다.
또한, MySQL레벨에서 관리되는 락으로써 공유 메모리 모델에 의존하기 떄문에 분산 시스템에 적합하지 않다. 그리고, 테이블 단위의 Lock을 걸게 되므로 성능에 영향을 미칠 수 있다.

그러나, MySQL 서버 메모리에서 동작하기 떄문에 빠르고, 관리가 쉬워서 사용했다.
또한, 진행했던 프로젝트에서 데이터 손실이 생기면 안되었기 때문에, 중요한 범위를 잠궈 다른 클라이언트가 실행하지 못하도록 설정하려고 했다.
데드락이 발생할 수 있는 부분은 네임드락을 순차적으로 처리함에 따라 발생가능성을 방지했다.

Named Lock 함수

Get_Lock(lock_name, timeout)

  • name lock은 이름으로 식별되는 잠금으로써, 이름을 받고 설정된 timeout을 기준으로 기다리는 시간을 설정하고 Lock을 획득한다.

Release_Lock(lock_name)

  • lock_name을 가진 lock을 확인해 Lock을 해제한다.

Is_Free_Lock(lock_name)

  • lock_name을 가진 Lock을 사용가능한지 확인한다.

IS_Used_Lock(lock_name)

  • lock_name을 가진 Lock이 사용중인지 확인한다.

MySQL8.0 이후 부터는 중첩해서 걸 수 있게 되며 좀 더 복잡한 로직을 처리할 수 있게 됐다

Reference

https://techblog.woowahan.com/2631/
https://www.youtube.com/watch?v=ZXV6ZqMyJLg

profile
🐻‍❄️

1개의 댓글

comment-user-thumbnail
2023년 5월 8일

우와 분산락을 직접 구현하다니 멋져요!!
다음엔 완성된 분산락에 대한 설명을 들어보고싶어요!

답글 달기