MySQL에서 GET_LOCK
과 RELEASE_LOCK
으로 분산 락(distributed lock)을 구현할 수 있다.
원래는
Redis Distributed Lock를 사용하려다가 서버 구성하고 관리하는게 힘들어서 어차피 사용하는 MySQL에 적용했는데, 너무 잘 작동해서 Redis Distributed Lock 을 사용할 필요가 없어졌다.
-
-
동일 커넥션에서 GET_LOCK을 여러번하면 여러번 락이 잡힌다. 따라서 RELEASE_LOCK을 그 횟수만큼 동일 커넥션에서 반복해서 해주지 않으면 lock이 풀리지 않게 된다.
Lock 은 트랜잭션 commit/rollback 여부와 상관없이 작동한다. rollback 한다고해서 lock 이 풀리지는 않는다.
-
Lock 이름은 64글자 제한(from MySQL 5.7)
-- lock 잡기. 숫자 1은 lock 을 잡기 위해 대기할 수 있는 최대시간.
-- 이 시간안에 락을 잡지 못하면 0 반환.
SELECT get_lock('session key', 1);
-- 배타적으로 할 일.
-- 락 풀기
SELECT release_lock('session key');
MySQL 5.6은 GET_LOCK
을 동일 세션에서 연속 호출하면 앞선 Lock을 해지하고 다시 잡는다.
MySQL 5.7은 두번 이상 호출해도 앞선 락을 해지하지 않는다.
-
5.7 부터 하나의 세션에서 연속으로 동일 Lock 이름으로 Lock을 잡으면 그 횟수만큼 중복으로 Lock이 잡힌다.
SELECT get_lock('a', 1);
SELECT is_free_lock('a'); -> FALSE
SELECT get_lock('a', 1);
SELECT is_free_lock('a'); -> FALSE
-- release 시작
SELECT release_lock('a'); -> 1
SELECT is_free_lock('a'); -> FALSE
SELECT release_lock('a'); -> 1
SELECT is_free_lock('a'); -> TRUE
-- 이미 모든 Lock 해지 상태
SELECT release_lock('a'); -> NULL