행 버전 관리 기반 격리 수준 사용
행 버전 관리 프레임워크는 항상 SQL Server에 설정되어 있으며 여러 기능에 사용됩니다. 행 버전 관리 기반 격리 수준을 제공할 뿐만 아니라 MARS(Multiple Active Result Set) 세션과 트리거의 수정 내용을 지원하고 온라인 인덱스 작업을 위한 데이터 읽기를 지원하는 데 사용됩니다.
행 버전 관리 기반 격리 수준은 데이터베이스 수준에서 설정됩니다. 설정된 데이터베이스의 개체에 액세스하는 응용 프로그램은 모두 다음과 같은 격리 수준을 사용하여 쿼리를 실행할 수 있습니다.
다음 코드 예제에서는 READ_COMMITTED_SNAPSHOT 데이터베이스 옵션을 ON으로 설정하여 행 버전 관리를 사용하는 커밋된 읽기를 보여 줍니다.
ALTER DATABASE AdventureWorks2008R2 SET READ_COMMITTED_SNAPSHOT ON;
데이터베이스에 READ_COMMITTED_SNAPSHOT을 설정하면 커밋된 읽기 격리 수준으로 실행되는 모든 쿼리에 행 버전 관리가 사용됩니다. 즉, 읽기 작업 시 업데이트 작업이 차단되지 않습니다.
다음 코드 예에서는 ALLOW_SNAPSHOT_ISOLATION 데이터베이스 옵션을 ON으로 설정하여 스냅숏 격리를 보여 줍니다.
ALTER DATABASE AdventureWorks2008R2 SET ALLOW_SNAPSHOT_ISOLATION ON;
스냅숏 격리로 실행되는 트랜잭션은 스냅숏이 설정된 데이터베이스의 테이블에 액세스할 수 있습니다. 스냅숏이 설정되지 않은 테이블에 액세스하려면 격리 수준을 변경해야 합니다. 예를 들어 다음 코드 예제에서는 스냅숏 트랜잭션으로 실행되는 동안 두 테이블을 조인하는 SELECT 문을 보여 줍니다. 한 테이블은 스냅숏 격리가 설정되지 않은 데이터베이스에 속합니다. 스냅숏 격리에서 SELECT 문을 실행하면 실행이 실패합니다.
SET TRANSACTION ISOLATION LEVEL SNAPSHOT; BEGIN TRAN SELECT t1.col5, t2.col5 FROM Table1 as t1 INNER JOIN SecondDB.dbo.Table2 as t2 ON t1.col1 = t2.col2;
다음 코드 예제에서는 트랜잭션 격리 수준을 커밋된 읽기로 변경하도록 수정된 동일한 SELECT 문을 보여 줍니다. 이렇게 변경하면 SELECT 문이 성공적으로 실행됩니다.
SET TRANSACTION ISOLATION LEVEL SNAPSHOT; BEGIN TRAN SELECT t1.col5, t2.col5 FROM Table1 as t1 WITH (READCOMMITTED) INNER JOIN SecondDB.dbo.Table2 as t2 ON t1.col1 = t2.col2;
응용 프로그램 내에서 격리 수준을 설정하는 방법은 트랜잭션 격리 수준 조정을 참조하십시오.
행 버전 관리 기반 격리 수준을 사용하는 트랜잭션의 제한 사항
행 버전 관리 기반 격리 수준을 사용할 때 다음 제한 사항을 고려하십시오.
tempdb, msdb 또는 master에는 READ_COMMITTED_SNAPSHOT을 설정할 수 없습니다.
전역 임시 테이블은 tempdb에 저장됩니다. 스냅숏 트랜잭션 내의 전역 임시 테이블에 액세스할 때 다음 중 하나를 수행해야 합니다.
tempdb에서 ALLOW_SNAPSHOT_ISOLATION 데이터베이스 옵션을 ON으로 설정합니다.
격리 힌트를 사용하여 문에 대한 격리 수준을 변경합니다.
다음과 같은 경우 스냅숏 트랜잭션이 실패합니다.
스냅숏 트랜잭션이 시작된 후 데이터베이스에 액세스하기 전에 데이터베이스가 읽기 전용으로 설정됩니다.
여러 데이터베이스의 개체에 액세스하는 경우 스냅숏 트랜잭션이 시작된 후 데이터베이스에 액세스하기 전에 데이터베이스 복구를 수반하는 방식으로 데이터베이스 상태가 변경됩니다. 예를 들면 다음과 같습니다. 데이터베이스가 OFFLINE으로 설정되었다가 ONLINE으로 설정되거나 데이터베이스가 자동으로 닫히고 열리거나 데이터베이스가 분리되고 연결됩니다.
분산 분할된 데이터베이스의 쿼리를 포함하여 분산 트랜잭션은 스냅숏 격리로 지원되지 않습니다.
SQL Server는 여러 버전의 시스템 메타데이터를 보관하지 않습니다. 테이블의 DDL(데이터 정의 언어) 문이나 기타 데이터베이스 개체(인덱스, 뷰, 데이터 형식, 저장 프로시저 및 공용 언어 런타임 함수)는 메타데이터를 변경합니다. DDL 문이 개체를 수정하면 스냅숏 격리의 개체에 대한 동시 참조로 인해 스냅숏 트랜잭션이 실패합니다. READ_COMMITTED_SNAPSHOT 데이터베이스 옵션이 ON이면 커밋된 읽기 트랜잭션에 이러한 제한 사항이 없습니다.
예를 들어 데이터베이스 관리자가 다음 ALTER INDEX 문을 실행합니다.
USE AdventureWorks2008R2; GO ALTER INDEX AK_Employee_LoginID ON HumanResources.Employee REBUILD; GO
ALTER INDEX 문이 실행된 후 HumanResources.Employee 테이블을 참조하려고 하면 ALTER INDEX 문 실행 시 활성 상태인 모든 스냅숏 트랜잭션에 오류가 발생합니다. 행 버전 관리를 사용하는 커밋된 읽기 트랜잭션은 영향을 받지 않습니다.
[!참고]
BULK INSERT 작업을 수행할 때 대상 테이블 메타데이터가 변경될 수 있습니다. 제약 조건 검사를 해제한 경우를 예로 들 수 있습니다. 이렇게 대상 테이블 메타데이터가 변경되면 동시 스냅숏 격리 트랜잭션이 대량 삽입된 테이블에 액세스할 수 없습니다.