커서 동시성(데이터베이스 엔진)
MicrosoftSQL Server는 서버 커서에 대한 네 가지 동시성 옵션을 지원합니다.
READ_ONLY
OPTIMISTIC WITH VALUES
OPTIMISTIC WITH ROW VERSIONING
SCROLL LOCKS
READ_ONLY
커서를 통한 위치 지정 업데이트는 지원되지 않으며 결과 집합을 구성하는 행에 대해 잠금이 보유되지 않습니다.OPTIMISTIC WITH VALUES
낙관적 동시성 제어는 트랜잭션 제어 이론의 표준입니다. 낙관적 동시성 제어는 커서가 열린 후 행이 업데이트되는 동안 다른 사용자 또는 프로세스가 행을 업데이트할 가능성이 거의 없는 경우에 사용합니다. 이 옵션으로 커서를 열면 원본 행에 대한 잠금이 보유되지 않아 처리량이 최대화됩니다. 사용자가 행을 수정하려고 하면 행을 마지막 인출할 때 검색된 값과 현재 행 값이 비교됩니다. 변경된 값이 있으면 서버는 다른 사용자 또는 프로세스가 행을 이미 업데이트했다는 것을 인식하여 오류를 반환합니다. 값이 같으면 서버가 수정을 수행합니다.이 동시성 옵션을 선택하면 사용자나 프로그래머가 때때로 발생하는 다른 사용자의 행 수정 오류를 처리해야 합니다. 이 오류를 받은 응용 프로그램은 일반적으로 커서를 새로 고치고 새 값을 얻은 다음 사용자가 새 값을 수정할 것인지를 결정하게 합니다. SQL Server 6.5 이전 버전에서 text, ntext 및 image 열은 동시성 비교에 사용되지 않습니다.
OPTIMISTIC WITH ROW VERSIONING
이 낙관적 동시성 제어 옵션은 행 버전 지정을 기반으로 합니다. 행 버전을 지정하면 행을 커서로 읽은 후 행이 변경되었는지의 여부를 서버가 결정할 때 사용하는 일부 유형의 버전 식별자가 기본 테이블에 있어야 합니다. SQL Server에서는 이 기능이 데이터베이스에서 상대적 수정 시퀀스를 나타내는 이진 숫자인 timestamp 데이터 형식에 의해 제공됩니다. 각 데이터베이스에는 전역적 현재 타임스탬프 값인 **@@**DBTS가 있습니다. timestamp 열이 있는 행이 어떤 방법으로든 수정될 때마다 SQL Server는 현재 **@@**DBTS 값을 timestamp 열에 저장하고 **@@**DBTS를 증가시킵니다. 테이블에 timestamp 열이 있으면 타임스탬프가 행 수준에 적용됩니다. 그러면 서버가 행의 현재 타임스탬프 값과 행이 마지막으로 인출될 때 저장된 타임스탬프 값을 비교하여 행의 업데이트 여부를 결정합니다. 서버는 모든 열의 값을 비교할 필요 없이 timestamp 열만 비교하면 됩니다. 응용 프로그램이 timestamp 열이 없는 테이블의 행 버전을 지정하여 낙관적 동시성을 요청하면 커서는 기본적으로 값을 기반으로 낙관적 동시성을 제어합니다.[!참고]
원격 데이터 원본에 대해 열린 커서의 경우 원격 원본에 타임스탬프 열이 포함되지 않으면 커서를 통해 업데이트가 지원되지 않습니다.
SCROLL LOCKS
이 옵션은 응용 프로그램이 커서 결과 집합으로 읽을 때 원본 데이터베이스 행을 잠그는 비관적 동시성 제어를 구현합니다. 서버 커서를 사용하면 커서로 읽을 때 행에 대해 업데이트 잠금이 얻어집니다. 트랜잭션 내에서 커서를 열면 트랜잭션이 커밋되거나 롤백될 때까지 트랜잭션 업데이트 잠금이 보유됩니다. 커서 잠금은 다음 행을 인출할 때 삭제됩니다. 커서가 트랜잭션 밖에서 열려 있으면 다음 행을 인출할 때 잠금이 삭제됩니다. 따라서 사용자가 전체 비관적 동시성 제어를 원할 때마다 트랜잭션에서 커서를 열어야 합니다. 업데이트 잠금은 다른 태스크가 업데이트 또는 배타적 잠금을 얻지 못하게 하여 다른 태스크가 행을 업데이트하지 못하게 합니다. 그러나 업데이트 잠금은 공유 잠금을 차단하지 못하므로 다른 태스크가 업데이트 잠금과 읽기를 함께 요청하지 않는 한 행을 읽지 못하게 할 수 없습니다.
스크롤 잠금
이러한 커서 동시성 옵션은 커서 정의의 SELECT 문에서 지정한 잠금 힌트에 따라 스크롤 잠금을 생성할 수 있습니다. 스크롤 잠금은 인출 시 각 행에 대해 얻어지며 다음 인출 작업 또는 커서가 잠길 때 중 먼저 일어나는 시기까지 보유됩니다. 다음 인출 시 서버는 새 인출에서 행에 대해 스크롤 잠금을 얻은 다음 이전 인출에서 행에 대해 얻은 스크롤 잠금을 해제합니다. 스크롤 잠금은 트랜잭션 잠금과 별개의 것이며 커밋 또는 롤백 작업 후까지 지속될 수 있습니다. 커밋 시 커서를 닫는 옵션을 해제하면 COMMIT을 수행해도 열려 있는 커서가 닫히지 않으며 커밋 후에도 스크롤 잠금이 보유되어 인출된 데이터의 격리가 유지됩니다.
얻은 스크롤 잠금의 유형은 커서 동시성 옵션과 커서 SELECT 문의 잠금 힌트에 따라 달라집니다.
[!참고]
스크롤 잠금은 키 집합 커서와 동적 커서에서만 지원됩니다.
잠금 힌트 |
읽기 전용 |
값이 있는 낙관적 동시성 |
행 버전을 지정한 낙관적 동시성 |
잠금 |
---|---|---|---|---|
힌트 없음 |
- |
- |
- |
업데이트 |
NOLOCK* |
- |
- |
- |
- |
HOLDLOCK |
- |
- |
- |
업데이트 |
UPDLOCK |
- |
- |
- |
업데이트 |
TABLOCKX |
- |
- |
- |
업데이트 |
나머지 |
- |
- |
- |
업데이트 |
*NOLOCK 힌트를 지정하면 이 힌트가 지정된 테이블이 커서를 통해 읽기 전용이 됩니다.
커서 동시성 옵션 지정
동시성 옵션은 각 커서 환경에 따라 다르게 지정됩니다.
Transact-SQL 커서
DECLARE CURSOR 문에서 READ_ONLY, SCROLL_LOCK 및 OPTIMISTIC 키워드를 지정합니다. OPTIMISTIC 키워드는 행 버전을 지정한 낙관적 동시성을 지원하며 Transact-SQL 커서는 값이 있는 낙관적 동시성 옵션을 지원하지 않습니다.
ADO 응용 프로그램
Recordset 개체의 LockType 속성에 adLockReadOnly, adLockPessimistic, adLockOptimistic 또는 adLockBatchOptimistic을 지정합니다.
ODBC 응용 프로그램
문 특성 SQL_ATTR_CONCURRENCY를 SQL_CONCUR_READ_ONLY, SQL_CONCUR_ROWVER, SQL_CONCUR_VALUES 또는 SQL_CONCUR_LOCK으로 설정합니다.