다음을 통해 공유


트랜잭션 격리 수준(ODBC)

트랜잭션 격리 수준은 트랜잭션 격리가 성공하는 정도의 측정값입니다. 특히 트랜잭션 격리 수준은 다음 현상의 존재 또는 부재에 의해 정의됩니다.

  • 더티 읽기 더티 읽기는 트랜잭션이 아직 커밋되지 않은 데이터를 읽을 때 발생합니다. 예를 들어 트랜잭션 1이 행을 업데이트한다고 가정합니다. 트랜잭션 2는 트랜잭션 1이 업데이트를 커밋하기 전에 업데이트된 행을 읽습니다. 트랜잭션 1이 변경 내용을 롤백하는 경우 트랜잭션 2에는 존재하지 않는 것으로 간주되는 읽기 데이터가 있습니다.

  • 재현할 수 없는 읽기 트랜잭션 이 동일한 행을 두 번 읽지만 매번 다른 데이터를 가져오는 경우 재현할 수 없는 읽기 가 발생합니다. 예를 들어 트랜잭션 1이 행을 읽는다고 가정합니다. 트랜잭션 2는 해당 행을 업데이트하거나 삭제하고 업데이트 또는 삭제를 커밋합니다. 트랜잭션 1이 행을 다시 읽는 경우 다른 행 값을 검색하거나 행이 삭제되었음을 검색합니다.

  • 가상 A 가상 은 검색 조건과 일치하지만 처음에는 표시되지 않는 행입니다. 예를 들어 트랜잭션 1이 일부 검색 조건을 충족하는 행 집합을 읽는다고 가정합니다. 트랜잭션 2는 트랜잭션 1의 검색 조건과 일치하는 새 행(업데이트 또는 삽입을 통해)을 생성합니다. 트랜잭션 1이 행을 읽는 문을 다시 검색하는 경우 다른 행 집합을 가져옵니다.

SQL-92에 정의된 네 가지 트랜잭션 격리 수준은 이러한 현상 측면에서 정의됩니다. 다음 표에서 "X"는 발생할 수 있는 각 현상을 표시합니다.

트랜잭션 격리 수준 더티 읽기 재현할 수 없는 읽기 팬텀
커밋되지 않은 읽기 X X X
커밋된 읽기 -- X X
반복 읽기 -- -- X
직렬화 가능 -- -- --

다음 표에서는 DBMS가 트랜잭션 격리 수준을 구현할 수 있는 간단한 방법을 설명합니다.

Important

대부분의 DBMS는 동시성을 높이기 위해 이러한 구성표보다 더 복잡한 체계를 사용합니다. 이러한 예제는 설명 목적으로만 제공됩니다. 특히 ODBC는 특정 DBMS가 트랜잭션을 서로 격리하는 방법을 규정하지 않습니다.

트랜잭션 격리 가능한 구현
커밋되지 않은 읽기 트랜잭션은 서로 격리되지 않습니다. DBMS가 다른 트랜잭션 격리 수준을 지원하는 경우 해당 수준을 구현하는 데 사용하는 메커니즘을 무시합니다. 다른 트랜잭션에 부정적인 영향을 주지 않도록 커밋되지 않은 읽기 수준에서 실행되는 트랜잭션은 일반적으로 읽기 전용입니다.
커밋된 읽기 트랜잭션은 다른 트랜잭션에 의해 쓰기 잠금이 해제될 때까지 대기합니다. 이렇게 하면 "더티" 데이터를 읽을 수 없습니다.

트랜잭션은 다른 트랜잭션이 행을 업데이트하거나 삭제하지 못하도록 현재 행에 읽기 잠금(행만 읽는 경우) 또는 쓰기 잠금(행을 업데이트하거나 삭제하는 경우)을 보유합니다. 트랜잭션은 현재 행에서 이동할 때 읽기 잠금을 해제합니다. 커밋되거나 롤백될 때까지 쓰기 잠금을 유지합니다.
반복 읽기 트랜잭션은 다른 트랜잭션에 의해 쓰기 잠금이 해제될 때까지 대기합니다. 이렇게 하면 "더티" 데이터를 읽을 수 없습니다.

트랜잭션은 애플리케이션으로 반환되는 모든 행에 대해 읽기 잠금을 유지하고 삽입, 업데이트 또는 삭제하는 모든 행에 대한 쓰기 잠금을 보유합니다. 예를 들어 트랜잭션에 SQL 문 SELECT * FROM Orders가 포함된 경우 애플리케이션에서 가져올 때 트랜잭션이 행을 읽기/잠급니다. 트랜잭션에 SQL 문 DELETE FROM Orders WHERE Status = 'CLOSED'가 포함된 경우 트랜잭션은 행을 삭제할 때 행을 쓰기 잠급니다.

다른 트랜잭션은 이러한 행을 업데이트하거나 삭제할 수 없으므로 현재 트랜잭션은 변경할 수 없는 읽기를 방지합니다. 트랜잭션은 커밋되거나 롤백될 때 잠금을 해제합니다.
직렬화 가능 트랜잭션은 다른 트랜잭션에 의해 쓰기 잠금이 해제될 때까지 대기합니다. 이렇게 하면 "더티" 데이터를 읽을 수 없습니다.

트랜잭션은 영향을 미치는 행 범위에서 읽기 잠금(행만 읽는 경우) 또는 쓰기 잠금(행을 업데이트하거나 삭제할 수 있는 경우)을 보유합니다. 예를 들어 트랜잭션에 SQL 문 SELECT * FROM Orders가 포함된 경우 범위는 전체 Orders 테이블입니다. 트랜잭션은 테이블을 읽기 잠금하고 새 행을 삽입할 수 없습니다. 트랜잭션에 SQL 문 DELETE FROM Orders WHERE Status = 'CLOSED'가 포함된 경우 범위는 상태가 "CLOSED"인 모든 행입니다. 트랜잭션은 Orders 테이블의 모든 행을 "CLOSED"로 잠그고 결과 행의 상태가 "CLOSED"이 되도록 행을 삽입하거나 업데이트할 수 없습니다.

다른 트랜잭션은 범위의 행을 업데이트하거나 삭제할 수 없으므로 현재 트랜잭션은 변경할 수 없는 읽기를 방지합니다. 다른 트랜잭션은 범위에 행을 삽입할 수 없으므로 현재 트랜잭션은 가상을 방지합니다. 트랜잭션은 커밋되거나 롤백될 때 잠금을 해제합니다.

트랜잭션 격리 수준은 트랜잭션의 자체 변경 내용을 보는 기능에 영향을 주지 않는다는 점에 유의해야 합니다. 트랜잭션은 변경 내용을 항상 볼 수 있습니다. 예를 들어 트랜잭션은 두 개의 UPDATE 명세서로 구성될 수 있으며, 그 중 첫 번째는 모든 직원의 급여를 10% 인상하고 두 번째는 직원의 급여를 해당 금액으로 설정합니다. 이는 두 번째 UPDATE 문이 첫 번째의 결과를 볼 수 있기 때문에 단일 트랜잭션으로만 성공합니다.