[MySQL] 쓰기 락 읽기 락

기훈·2024년 3월 8일

MySQL

목록 보기
20/23

락을 통해 동시성을 제어할 때는, 락의 범위를 최소화 하는 것이 중요하다.
(락의 범위가 길어진다 -> 커넥션 풀 점유 시간이 길어진다 -> 커넥션 풀의 자원이 줄어든다)

MySQL

  1. 트랜잭션의 커밋 혹은 롤백 시점에 잠금이 풀린다. -> 트랙잭션이 곧 락의 범위이다 -> 트랜잭션의 범위를 최소화 해야 한다.

  2. 기본적으로 읽기 락 (Shared Lock)과 쓰기 락 (Exclusive Lock)이 있다. 매번 잠금을 발생할 경우, 성능저하를 피할 수 없다. 따라서 일반 SECLET는 Nonblocking으로 동작한다.
    ( undo log를 통해 관리하여 가능하다)

  • 읽기 락 (Shared Lock): 데이터의 동시 읽기는 가능하지만, 쓰기는 허용되지 않는다. 이는 데이터의 일관성을 유지하면서 여러 트랜잭션이 동시에 읽을 수 있도록 한다. (SELECT ... FOR SHARE)

  • 쓰기 락 (Exclusive Lock): 해당 데이터에 대한 독점적인 접근을 제공. 쓰기 작업을 하는 동안 다른 트랜잭션이 해당 데이터를 읽거나 쓸 수 없으며, 이는 데이터의 무결성을 보장한다. (SELECT FRO UPDATE 또는 DELETE)

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

    lock mode = x (쓰기락)


3번에 대한 예제

  1. POST 테이블에 유저아이디 1로 검색을 하면 4개의 데이터가 존재한다.

  2. memberId를 인덱스로 설정한다.

  3. 쓰기락을 실행하며 데이터를 조회한다.

  4. 새로운 창에서 데이터를 쿼리를 실행하면 락이걸려 조회되지 않는다.

    두개의 트랜잭션이 결과가 다른데 조회 되지않는다.
    memberId가 1인 모든 컬럼에 락이 걸리기 때문이다.
    실제 확인을 해보면 다음과 같은 결과가 나온다,

    SELECT * from performance_schema.data_locks; // 실행중인 락 조회

    마지막으로 다른 콘솔창에서 아래의 명령어를 실행해 보면 처음에 실행한 트랜잭션이 락이 걸려있는 것을 확인할 수 있다.

    SELECT * from information_schema.innodb_trx; // 실행중인 트랜잭션 조회

이번엔 인덱스가 설정되지 않은 컬럼을 조건으로 주고 락을 걸어보자
(createdDate는 인덱스 컬럼이 아니다.)

실행중인 락의 개수를 보면 where조건에 해당하는 컬럼만큼 락이 설정된 것을 볼 수 있다.


결론

MYSQl은 컬럼이 아닌 인덱스에 락이 설정된다.

인덱스가 없는 조건으로 락을 설정했을 때, 불필요한 데이터가 잠길 수 있으므로 주의해야 한다.

0개의 댓글