トランザクションレベルのスナップショット(ReadCommmittedSnapshotIsolationではない)を使用して「更新の競合」を作成する方法の例はありますか?
エラーメッセージの例:
更新の競合により、スナップショット分離トランザクションが中止されました。スナップショット分離を使用して、データベース「FoodDatabase」のテーブル「Food」に直接または間接的にアクセスして、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。
以下は機能していません:
create database FoodDatabase;
alter database FoodDatabase SET ALLOW_SNAPSHOT_ISOLATION ON;
create table dbo.food
(
FoodId int primary key identity(1,1),
FoodDesc varchar(255) null,
)
insert into dbo.food
values ('broccoli'), ('strawberry')
Transaction Session 1:
set transaction isolation level snapshot
begin transaction -- do not commit transaction yet
update Food
set FoodDesc = 'Grape' where FoodId = 1
Transaction Session 2:
set transaction isolation level snapshot
begin transaction -- do not commit transaction yet
update food
update Food
set FoodDesc = 'Lettuce' where FoodId = 1
SQL Serverバージョンを使用しています:
Microsoft SQL Server 2017(RTM-CU1)(KB4038634)-14.0.3006.16(X64)
この順序でスクリプトを実行すると、Update Conflict
をシミュレートできます。
接続1
CREATE DATABASE FoodDatabase;
GO
ALTER DATABASE FoodDatabase SET ALLOW_SNAPSHOT_ISOLATION ON;
GO
USE [FoodDatabase];
GO
CREATE TABLE dbo.food
(
FoodId int PRIMARY KEY IDENTITY(1,1),
FoodDesc varchar(255) null,
);
GO
INSERT INTO dbo.food
VALUES ('broccoli'), ('strawberry');
GO
--Transaction Session 1:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRANSACTION -- do not commit transaction yet
UPDATE dbo.Food
SET FoodDesc = 'Grape' WHERE FoodId = 1;
出力:
(2行が影響を受けました)
(1行が影響を受けました)
接続2
--Transaction Session 2:
USE [FoodDatabase];
GO
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRANSACTION -- do not commit transaction yet
UPDATE dbo.Food
SET FoodDesc = 'Lettuce' WHERE FoodId = 1;
接続2からのセッションは接続1によってブロックされます。ロックの詳細を表示するには、Adam Machanicによって作成された sp_whoIsActive を使用します。
<lock_type>keylock</lock_type>
<database_name>FoodDatabase</database_name>
<hobt_id>72057594043105280</hobt_id>
<schema_name>dbo</schema_name>
<object_name>food</object_name>
Connection 1ウィンドウに戻り、COMMIT
ステートメントを実行します。 Connection 2メッセージタブに次のエラーメッセージが表示されます。
メッセージ3960、レベル16、状態3、行6スナップショット分離トランザクションは、更新の競合のために中止されました。スナップショット分離を使用して、データベース 'FoodDatabase'のテーブル 'dbo.food'に直接または間接的にアクセスして、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。
役立つリソース: