오라클은 읽기(SELECT)에 대해선 Lock을 쓰지 않는다.
오라클은 다중 버전 동시성 제어 메커니즘(MVCC, Multi-Version Concurrency Control)으로 구현됐기 때문에 Lock 없이도 문장 수준 읽기 일관성이 유지되기 때문이다.
다만 DML과 Select ... for update에 대해선 Lock이 필요하다.
repeatable read, 한 트랜잭션 내에 동일한 로우를 두 번 읽고, 이의 일관성을 보장하기 위해
첫번째 select에 for update를 달면 '나중에 이 로우에 대해서 select를 또 쓸 수 있으니 다른 트랜잭션에 의한 수정 작업을 막아라'라는 말이 되며, 그 로우에 lock이 걸리게 된다.
DML의 경우, 변경 중인 로우에 대해 그 수정 작업이 끝나기도 전에 다른 트랜잭션에 의해 수정되는 것을 막기 위해 Lock을 걸게 된다.
오라클에서 Lock의 여부를 판별하는 기준은 다음과 같다.
오라클에서 Lock은 크게 로우 lock, 테이블 lock으로 나뉜다.
로우 Lock은 insert, update, delete 같은 DML문이나 select ... for update를 실행한 트랜잭션에 의해 설정되며,
이 트랜잭션이 커밋 또는 롤백할 때까지 다른 트랜잭션은 해당 로우를 변경할 수 없다.
레코드를 변경하고 있다면, 테이블 구조도 변하지 말아야 한다.
따라서 한 트랜잭션이 로우 Lock을 얻는 순간, 테이블도 같이 Lock이 걸리면서 그 테이블에 대한 DDL이 금지된다.
테이블 Lock에는 다섯 종류가 있다.
대표적으로 select ... for update 일 때는 RS 모드로, DML 일 때는 RX 모드로 Lock을 얻는다.
테이블 Lock이라고 해서 테이블에 있는 전체 로우에 Lock이 걸리는 게 아니라,
해당 테이블이 현재 어떤 작업을 수행 중인지를 알리는 일종의 flag이다.
후행 트랜잭션은 어떤 테이블 lock이 설정돼 있는지만 보고도 그 테이블로의 진입 여부를 결정할 수 있다.
(로우에 대해 일일히 검사를 해보지 않고)