OK、帰宅してテストしました。これが観察です。
CREATE DATABASE TEST;
GO
CREATE TABLE TABLE1
(
ID tinyint,
Details varchar(10)
);
GO
INSERT INTO TABLE1
VALUES (1, 'Original');
GO
SELECT
name,
snapshot_isolation_state_desc,
is_read_committed_snapshot_on
FROM sys.databases
WHERE name = 'TEST';
GO
両方の設定がオフになっていることを確認した最初のテスト。
クエリ1
USE TEST;
BEGIN TRAN
UPDATE TABLE1
SET Details = 'Update'
WHERE ID = 1;
--COMMIT;
--ROLLBACK;
GO
クエリ2
USE TEST;
SELECT ID, Details
FROM TABLE1
WHERE ID = 1;
GO
このテストでは、クエリ2はクエリ1がコミットするのを待っています。dm_tran_locksDMVは、クエリ1によってTABLE1の排他ロックが発生したことを示しています。
USE TEST;
SELECT
DB_NAME(tl.resource_database_id) AS DBName,
resource_type,
OBJECT_NAME(resource_associated_entity_id) AS tbl_name,
request_mode,
request_status,
request_session_id
FROM sys.dm_tran_locks tl
WHERE
resource_database_id = db_id('TEST')
AND resource_type = 'OBJECT'
2番目のテスト、前のトランザクションのロールバック、READ_COMMITTED_SNAPSHOTをオンに設定しますが、ALLOW_SNAPSHOT_ISOLATIONはオフのままにします。
ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT ON
WITH ROLLBACK IMMEDIATE;
GO
クエリ1を実行し、クエリ2を実行します。DMVはクエリ1に排他ロックが発生したことを示しますが、クエリ2はクエリ1なしで「オリジナル」の詳細を返し、トランザクションをコミットします。READ_COMMITTED行のバージョン管理が行われているようです。
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
クエリ1とクエリ2を追加し、クエリ1またはクエリ2を実行するとエラーが返されます。このデータベースではスナップショット分離が許可されていないため、スナップショット分離トランザクションはデータベース「TEST」にアクセスできませんでした。ALTER DATABASEを使用して、スナップショット分離を許可します。
3番目のテスト、前のトランザクションをロールバックします。READ_COMMITTED_SNAPSHOT OFFおよびALLOW_SNAPSHOT_ISOLATION ONを設定します。
ALTER DATABASE TEST
SET READ_COMMITTED_SNAPSHOT OFF
WITH ROLLBACK IMMEDIATE;
GO
ALTER DATABASE TEST
SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
クエリ1を実行してから、クエリ2を実行します。DMVは、クエリ1によって発生した排他ロックを示します。クエリ2は、クエリ1の完了を待機しているようです。ALLOW_SNAPSHOT_ISOLATIONをオンにしても、READ COMMITTED行のバージョン管理は有効になりません。
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
クエリ1とクエリ2の両方に追加します。クエリ1を実行してからクエリ2を実行します。DMVがクエリ1に排他ロックがかかっていることを示している間、クエリ2は「Original」で詳細を返します。スナップショット分離が適切に行われているようです。
テストからの観察は、READ_COMMITTED_SNAPSHOT
それ自体がALLOW_SNAPSHOT_ISOLATION
設定に関係なくREAD COMMITTED行のバージョン管理を有効化/無効化すること、およびその逆を示しています。