데이터베이스 일관성은 DBMS 성능을 측정하는 중요한 지표 중 하나입니다. 현재 대부분의 상용 데이터베이스(DB2, SQL Server)는 동시성 제어를 위해 2단계 잠금(2PL) 프로토콜을 사용하여 동시 트랜잭션 실행의 직렬화를 보장합니다. 하지만 2PL은 데이터를 읽거나 쓰기 전에 잠가야 합니다. 블로킹 호환성 행렬에서 S 락(공유 잠금)과 X 잠금(독점 잠금)은 호환되지 않으므로, 트랜잭션 1이 데이터 A(그리고 S 잠금)에 대해 읽기 작업을 수행하고 트랜잭션 2가 데이터에 쓰기를 원할 때(X 잠금을 추가), 트랜잭션 2는 트랜잭션 1이 데이터 A에 대한 S 잠금을 해제할 때까지 기다려야 합니다. 다중 버전 동시성 제어(MVCC)는 이 문제를 잘 해결합니다. 다중 버전 시스템에서는 각 쓰기 데이터가 새로운 버전을 생성하며, 읽기 연산이 필요에 따라 적절한 버전을 읽을 수 있어 읽기와 쓰기 연산이 서로 차단되지 않습니다. MVCC는 동시성을 증가시키지만, 동시에 여러 버전을 유지하는 데 따른 저장 오버헤드를 발생시킵니다.
Microsoft SQL Server 데이터베이스 엔진은 기존 트랜잭션 격리 수준을 새롭게 구현한 '커밋드 리드(commitd)'를 도입했으며, 이는 행 버전 관리(row versioning)를 이용해 문(table-level) 스냅샷을 제공합니다. SQL Server 데이터베이스 엔진은 또한 트랜잭션 격리의 새로운 수준인 스냅샷을 도입하여 행 버전 관리도 사용하는 트랜잭션 수준 스냅샷을 제공합니다.
READ_COMMITTED_SNAPSHOT 데이터베이스 옵션을 ON으로 설정하면 행 버전 관리(row versioning)를 통해 커밋된 읽기 격리가 가능합니다. ALLOW_SNAPSHOT_ISOLATION 데이터베이스 옵션을 ON으로 설정하면 스냅샷 격리가 활성화됩니다. 데이터베이스에서 두 가지 옵션이 활성화되면 데이터베이스 엔진은 수정된 각 행의 버전을 유지합니다. 트랜잭션이 행을 변경할 때마다, 수정 전 행의 이미지가 버전 저장소의 페이지에 복사됩니다. 버전 저장소는 tempdb 내 데이터 페이지들의 집합입니다. 트랜잭션 수정 라인이 여러 개 있다면, 그 라인의 여러 버전이 버전 체인으로 연결됩니다. 행 버전 관리 방식을 이용한 읽기 작업은 트랜잭션이나 문이 시작될 때 커밋된 각 행의 마지막 버전을 가져옵니다.
SQL Server 2008용이거나 SQL Server에 새로 도입된 애플리케이션은 READ_COMMITTED_SNAPSHOT 데이터베이스 옵션이 켜져 있을 때 읽기 커밋의 트랜잭션 격리 수준을 지정하여 행 버전 관리(row versioning)를 사용하여 읽기 커밋의 격리를 구현합니다. 모든 리드는 문장이 시작될 때 커밋된 행 버전을 봅니다. 이렇게 하면 데이터의 명문 수준 스냅샷을 제공합니다.
SQL Server용으로 작성된 애플리케이션은 ALLOW_SNAPSHOT_ISOLATION 데이터베이스 옵션이 켜져 있을 때 스냅샷 트랜잭션 격리 수준을 지정하여 스냅샷 격리를 구현합니다. 스냅샷 트랜잭션의 모든 읽기는 트랜잭션이 시작될 때 커밋된 행의 버전을 봅니다. 이렇게 하면 데이터의 트랜잭션 수준 스냅샷을 제공합니다.
행 기반 격리 레벨을 사용하는 트랜잭션의 경우, 읽기는 데이터에 대한 공유 락을 요청하지 않습니다. 즉, 행 버전 관리(row versioning)를 사용하는 리더가 다른 리더나 라이터가 동일한 데이터에 접근하는 것을 막지 않습니다. 마찬가지로, 작가는 독자의 길을 막지 않습니다. 하지만 작가들은 서로에게 방해가 됩니다(행 버전 관리 때문에 격리된 상태일 때조차도요). 두 쓰기 연산이 동시에 동일한 데이터를 수정할 수 없습니다.
스냅샷 격리 기능은 SQL Server 2008의 잠금 프레임워크를 확장하여 애플리케이션이 데이터 수정이 발생하기 전에 값을 확인할 수 있도록 합니다. 이렇게 하면 애플리케이션이 잠기는 것을 방지하면서도 실제로 제출된 데이터를 제공합니다. SQL Server 2008의 Read Committed Snapshot은 데이터베이스 관리자가 활성화해야 하며, 읽기 전용 트랜잭션으로 데이터를 읽을 수 있습니다. 따라서 SI의 읽기 전용 트랜잭션에 대한 동시성 제어는 매우 우수하지만, 업데이트 트랜잭션에 대해서는 불분명합니다. 장기 업데이트 트랜잭션이 단기 고수준 트랜잭션과 경쟁하는 것은 더 불리합니다. 데이터베이스 간 트랜잭션이 모든 데이터베이스가 설정한 것이 아니라 스냅샷 격리(SI) 표준을 사용하려 하면 트랜잭션이 실패합니다. 이로 인해 확장성에 분명히 장애물이 생깁니다. 마이크로소프트가 SQL 92 명세보다 더 강력한 자체 SI를 구현하려면 아직 갈 길이 멀어 보입니다.
수정 전에 이전 버전의 복사본을 만들면, 이후 모든 읽기 작업이 복사된 버전을 읽고, 수정 과정에서 새로운 버전이 생성됩니다. 이렇게,읽기와 쓰기 작업은 서로를 차단하지 않습니다. 이 라인 버전 관리 메커니즘을 사용하는 장점은 프로그램의 동시성이 비교적 높다는 점이지만, 사용자가 더러운 데이터를 읽지는 않더라도 수정 중이며 만료 직전의 데이터 값일 수 있다는 단점이 있습니다. 이 만료된 값을 기준으로 데이터를 수정하면 논리적 오류가 발생합니다。
SQL 명령어:
참고 링크:
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다.
|