Lock을 쓰는 것과 트랜잭션 고립수준을 높이는 것의 차이?

태그
데이터베이스
보통 데이터베이스에서 다중의 사용자가 하나의 데이터를 접근해서 쓰려는 경우에 생기는 문제를 막기 위해 생각할 수 있는 두가지 해결 방식이 존재한다.
  • Lock 사용하기
  • 트랜잭션의 고립 수준 높이기
 
그러나 두개는 다르다. 간단히 개념적으로 놓고 보면
  • Lock
    • 특정 자원에 대한 배타적 접근
  • 트랜잭션
    • 여러 작업의 연속적인 처리의 일관성과 데이터의 정합성 보장
 
가장 혼동할 수 있는 포인트는 트랜잭션의 고립 수준을 높이면, Lock과 다를바 없는 것이 아닌가? 반은 맞고 반은 틀리다.
  • 엄밀히 말해 트랜잭션을 통해 접근하는 건 말 그대로 여러 작업을 그냥 하나로 묶어서 처리하겠다는 개념일 뿐이다.
  • 보통 트랜잭션의 고립수준이 높아지니까 알아서 Lock을 쓰지 않아도 데이터에 대한 접근의 고립 수준을 높여주겠지 라고 생각할 수 있지만
  • 실제로는 트랜잭션의 고립수준이 높아질 수록 트랜잭션이 Lock을 더 많이 거는 방식으로 대응하는 것이다.
  • 즉, 트랜잭션의 고립 수준을 높이는 것을 구현하기 위해 Lock을 사용하는 것이다.
 
그래서 처음 질문에 돌아와서 생각해보면
  • Lock 사용하기
  • 트랜잭션의 고립 수준 높이기
  • 위 두개는 결국 둘다 “Lock 사용하기” 하는 것과 마찬가지이다.
  • 다만 Lock을 내가 직접 걸어서 Control 하냐, 트랜잭션 자체에서 매 작업에 대해 Lock을 자동으로 걸어주냐의 차이일 뿐이다.
 
실제 DB 에서도 트랜잭션 고립수준에 따라 Lock 거는 것이 달라지는지 확인해보자
  • MySQL(InnoDB)
    • REPEATABLE READ
    • This is the default isolation level for InnoDBConsistent reads within the same transaction read the snapshot established by the first read. This means that if you issue several plain (nonlocking) SELECT statements within the same transaction, these SELECT statements are consistent also with respect to each other. See Section 15.7.2.3, “Consistent Nonlocking Reads”.
      For locking reads (SELECT with FOR UPDATE or FOR SHARE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition.
      • For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it.
    • SERIALIZABLE
    • This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... FOR SHARE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)
    • REPEATABLE READ 에서는 Unique Index 를 사용하는 SELECT 쿼리 혹은 특정 Unique 조건 검색인 경우에 대해 Lock을 건다. 또한 Range 검색이되는 경우엔 Gap Lock을 건다.
    • SERIALIZABLE 에서는 REPEATABLE READ 와 다르게 모든 SELECT 쿼리에서 Lock 을 건다. (autocommit 옵션이 빠진 경우)

요약

📌
요약: 트랜잭션 고립 수준 높이기 → 고립이 높아질수록 트랜잭션에서 Lock을 건다.