[데이터베이스] 공유 락과 배타 락

이건회·2023년 8월 9일
0

데이터베이스

목록 보기
15/23
post-thumbnail

락은 데이터베이스의 무결성 유지를 위해 중요한 개념이다. 락의 개념 중 대표격으로 나뉘어지는 공유 락과 배타 락에 대해 포스팅하도록 하겠다.

공유 락

공유 락(Shared Lock)은 "읽는 동안 수정을 막는 락"이라고 생각하면 편하다. 한 트랜잭션에서 어떤 데이터에 대해 공유 락을 들고 있으면, 다른 트랜잭션에서는 이 데이터에 대한 갱신을 수행할 수 없고, 오직 읽기만 가능하다. 공유 락이 걸린 데이터가 있을 때, 다른 트랜잭션도 이 데이터에 대해 공유 락을 획득할 수 있으나, 배타 락을 획득할 수는 없다는 것이다.(아래에서 설명하겠지만 배타 락은 쓰기 위한 락이기 때문이다.)

배타 락

배타 락(Exclusive Lock)는 "쓰는 동안 수정을 막는 락"이라고 생각하면 편하다. 한 트랜잭션에서 어떠한 데이터에 대해 배타 락을 획득하면, 다른 트랜잭션은 해당 데이터에 대해 공유 락이나 배타 락을 획득할 수 없다.
그러나 주의할 점은, 공유 락을 획득할 수 없다는 것은 읽기를 막는다는 뜻이 아니다. 이는 밑에서 직접 설명하겠다.

MYSQL에서 공유 락과 배타 락 획득하기

공유 락

공유 락은 select 문에 for share 를 추가하는 형태로 획득할 수 있다.
select (열) from (테이블) for share

배타 락
배타 락은 select 문에 for update를 추가하는 형태로 획득할 수 있다.
select (열) from (테이블) for update

h2 database 통해 배타 락 실습하기

그렇다면 h2 database에서 별개의 스레드를 통해 배타 락을 걸어보도록 하겠다.(참고로 h2는 공유 잠금만 거는 문법이 존재하지 않는다.)

스레드 A를 시작하고 set autocommit false; 를 통해 트랜잭션을 시작한다

select * from item for update를 실행하여 item 테이블의 레코드에 대한 배타 락을 획득한다.


다른 콘솔에서 스레드 B를 시작하고, 동일하게 select * from item for update를 통해 배타 락을 획득하려 하지만, 이미 스레드 A가 해당 데이터에 대한 배타 락을 가지고 있으므로, 락 획득을 기다리다가 타임아웃이 나게 된다.

배타 락이 걸린 데이터에 update 쿼리를 실행해봤지만 역시 락이 풀리기를 기다리고 있다가 타임아웃이 나고 만다.

rollback 혹은 commit으로 트랜잭션을 종료시키고 나서야 update 쿼리가 정상적으로 실행되는 것을 확인할 수 있다.

배타 락이 걸린 데이터여도 select는 수행된다

가끔 한 트랜잭션에서 배타 락을 획득하면 다른 트랜잭션에서 갱신 및 조회가 불가능하다고 인식하는 경우가 있는데, 이는 옳지 않다. 위의 사진은 스레드 A에서 트랜잭션을 시작한 후, 배타 락을 획득한 경우다.

그러나 위와 같이 스레드 B에서 배타 락이 획득된 데이터에 대해 select를 수행했더니 결과가 정상적으로 조회되는 것을 확인할 수 있다.

select 쿼리는 단순한 행위에 해당하고, 락을 거는 것과는 전혀 다르다. 배타 락이 걸린 데이터에 대해 다른 스레드에서 공유 락과 배타 락을 얻을 수 있는 것이지, 여전히 커밋된 데이터에 대해 락 옵션을 걸지 않은 단순 select를 사용한다면 조회할 수 있다.

정리

공유 락

  • 어떤 데이터에 공유 락을 갖고 있으면 다른 트랜잭션에서 그 데이터를 갱신할 수 없다. 배타 락도 획득할 수 없다.
  • 어떤 데이터가 공유 락이 걸려도 다른 트랜잭션에서도 해당 데이터의 공유 락을 획득할 수 있다.

배타 락

  • 어떤 데이터에 배타 락을 갖고 있으면 다른 트랜잭션에서 그 데이터를 갱신할 수 없다. 배타 락도 획득할 수 없다.
  • 어떤 데이터가 배타 락이 걸리면 다른 트랜잭션에서 해당 데이터의 공유 락을 획득할 수 없다.

궁금한 점

  • 공유 락을 걸만한 뚜렷한 예시 상황이 떠오르지 않는다. 단순히 읽기 전용 락이라면 굳이 락을 걸만한 이유가 있나?

참고

https://velog.io/@soongjamm/Select-%EC%BF%BC%EB%A6%AC%EB%8A%94-S%EB%9D%BD%EC%9D%B4-%EC%95%84%EB%8B%88%EB%8B%A4.-X%EB%9D%BD%EA%B3%BC-S%EB%9D%BD%EC%9D%98-%EC%B0%A8%EC%9D%B4
https://hudi.blog/mysql-8.0-shared-lock-and-exclusive-lock/

profile
하마드

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

개발자로서 배울 점이 많은 글이었습니다. 감사합니다.

답글 달기