동시성 이슈 해결과 Lock에 대해서 공부하려면 Transaction 격리 수준에 대한 이해와 Lock이 무엇인지부터 알아야한다.
SELECT) operation을 수행 할 때 현재 DB의 값이 아닌 특정 시점의 DB snapshot을 읽어오는 것READ UNCOMMITTED
SELECT 쿼리를 실행할 때 아직 commit 되지 않은 데이터를 읽어올 수 있다
예를 들어
Transaction A에서 row를 삽입했다.
READ UNCOMMITTED level의 transaction B가 해당 row를 읽는다.
Transaction A가 rollback 된다.
이 경우에 transaction B는 실제로 DB에 한 번도 commit 되지 않은, 존재하지 않는 데이터를 읽음 → dirty read
InnoDB 엔진 (Mysql 5.5 버전 이상에서 적용, 이전에는 MyISAM) 은 일단 실행된 모든 쿼리를 DB에 적용. 아직 commit 되지 않았어도 적용.
즉, 특별히 log를 보고 특정 시점의 snapshot을 복구하는 consistent read를 하지 않고 그냥 해당 시점의 DB를 읽으면 dirty read
READ COMMITTED (Oracle의 Default)
REPEATABLE READ (Mysql에서의 Default)
반복해서 read operation을 수행하더라도 읽어 들이는 값이 변화하지 않는 정도의 isolation을 보장
처음으로 read(SELECT) operation을 수행한 시간을 기록
이후에는 모든 read operation마다 해당 시점을 기준으로 consistent read를 수행
transaction 도중 다른 transaction이 commit 되더라도 새로 commit 된 데이터는 보이지 않는다.
→ 다른 사용자가 commit 해도 그 바뀐 값이 이미 읽은 사용자한테는 변화한 것으로 보이지 않고 기존 값으로 보임
보통 gap lock을 활용, 조작을 가하려고 하는 row의 후보군을 다른 transaction이 건들지 못하도록 한다
SERIALIZABLE
REPEATABLE READ와 동일. SELECT 쿼리가 전부 SELECT ... FOR SHARE로 자동으로 변경 (Shared Lock을 거는 것)=> 동시성을 제어하기 위해서는 Transactional isolation level을 변경하는 것 만으로는 어려움이 있음
Transaction 격리 수준으로 동시성 제어가 힘들다면 Synchronized를 사용하면 안되나?
트랜잭션 처리의 순차성을 보장하기 위한 방법이다.
멀티 트랜잭션 환경에서 여러 요청이 들어올 시 데이터베이스의 일관성과 무결성을 유지하기 위해서 트랜잭션의 순차적인 진행을 보장하기 위해서는 Lock이 필요하다.
Row-level lock
(Query 1 in transaction A)
SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;
라는 쿼리를 실행 → t.c1의 값이 10인 index에 X lock이 걸림
이 때 다른 사용자 (or transaction) 가
(Query 2 in transaction B)
DELETE FROM t WHERE c1 = 10;
이런 쿼리 (c1 = 10을 삭제) 를 실행하려고 하면 사용자 A가 transaction을 commit 하거나 rollback 하기 전까지 (transaction이 끝나기전까지) 는 삭제할 수 없다.
Gap lock
DB index record의 gap에 걸리는 lock (gap이란 index 중 DB에 실제 record가 없는 부분)
조건에 해당하는 새로운 row가 추가되는 것을 방지
예를 들어 c1이라는 컬럼이 있는 테이블 t에는 c = 13, c= 17 이라는 두 컬럼이 있다하면
(Query 1 in transaction A)
SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
10 <= id <= 12, 14 <= id <= 16, 18 <= id <= 20에 해당하는 gap에 lock이 걸린다.
따라서 c = 15인 부분을 insert 하고자 해도 삽입이 되지 않는다.

데이터베이스 락
공유 잠금과 배타적 잠금의 차이
재고시스템으로 알아보는 동시성이슈 해결 방법
Lock으로 이해하는 Transactional isolation level
InnoDB 읽기 수준
Transactional 격리 수준