비교적 낮은 격리 수준(4)으로서 더티 읽기는 발생하지 않지만, 반복 불가능한 읽기와 유령 읽기는 발생할 수 있다. 즉, 트랜잭션 T1이 하나의 객체를 반복하여 조회하는 동안 다른 트랜잭션 T2에서의 삽입 또는 갱신이 허용되어, 트랜잭션 T1이 다른 값을 읽을 수 있다는 의미이다.
다음과 같은 규칙이 적용된다.
이 격리 수준은 배타 잠금에 대해서는 2단계 잠금을 따른다. 하지만 행에 대한 공유 잠금은 행이 조회된 직후 바로 해제되지만, 테이블에 대한 의도 잠금은 스키마에 대한 반복 가능한 읽기를 보장하기 위하여 트랜잭션이 종료될 때 해제된다.
SET TRANSACTION 문을 수행할 때 격리 수준의 다른 명칭으로 CURSOR STABILITY 키워드가 사용될 수 있다.
다음은 동시에 수행되는 트랜잭션의 격리 수준이 REPEATABLE READ CLASS with READ COMMITTED INSTANCES인 경우 한 트랜잭션에서 객체 읽기를 수행하는 동안 다른 트랜잭션이 새로운 레코드를 추가 또는 갱신할 수 있으므로 유령 읽기 및 반복 불가능한 읽기가 발생할 수 있으나, 테이블 스키마 갱신에 대해서는 반복 가능한 읽기를 보장함을 보여주는 예제이다.
session 1 |
session 2 |
---|---|
;autocommit off AUTOCOMMIT IS OFF
SET TRANSACTION ISOLATION LEVEL 4;
Isolation level set to: REPEATABLE READ SCHEMA, READ COMMITTED INSTANCES. |
;autocommit off AUTOCOMMIT IS OFF
SET TRANSACTION ISOLATION LEVEL 4;
Isolation level set to: REPEATABLE READ SCHEMA, READ COMMITTED INSTANCES. |
--creating a table
CREATE TABLE isol4_tbl(host_year integer, nation_code char(3)); INSERT INTO isol4_tbl VALUES (2008, 'AUS');
COMMIT; |
|
--selecting records from the table SELECT * FROM isol4_tbl; host_year nation_code =================================== 2008 'AUS' |
|
INSERT INTO isol4_tbl VALUES (2004, 'AUS');
INSERT INTO isol4_tbl VALUES (2000, 'NED');
/* able to insert new rows even if tran 2 uncommitted */ |
|
SELECT * FROM isol4_tbl;
/* phantom read may occur when tran 1 committed */ |
|
COMMIT; |
host_year nation_code =================================== 2008 'AUS' 2004 'AUS' 2000 'NED' |
INSERT INTO isol4_tbl VALUES (1994, 'FRA'); |
|
SELECT * FROM isol4_tbl;
/* unrepeatable read may occur when tran 1 committed */ |
|
DELETE FROM isol4_tbl WHERE nation_code = 'AUS' and host_year=2008;
/* able to delete rows while tran 2 is selecting rows*/ |
|
COMMIT; |
host_year nation_code =================================== 2004 'AUS' 2000 'NED' 1994 'FRA' |
ALTER TABLE isol4_tbl ADD COLUMN gold INT;
/* unable to alter the table schema until tran 2 committed */ |
|
/* repeatable read is ensured while tran_1 is altering table schema */
SELECT * FROM isol4_tbl; host_year nation_code =================================== 2004 'AUS' 2000 'NED' 1994 'FRA' |
|
|
COMMIT; |
SELECT * FROM isol4_tbl;
/* unable to access the table until tran_1 committed */ |
|
COMMIT; |
host_year nation_code gold =================================== 2004 'AUS' NULL 2000 'NED' NULL 1994 'FRA' NULL |