トランザクション分離レベルのスナップショットと切り捨て?


10

スナップショット分離とTRUNCATEに関して、私が予期していなかったこの動作に誰かが光を当てることができることを願っています。

データベース:スナップショット分離を許可= True; コミットされた読み取りスナップショットがオン= False。

手順1(長時間実行される複雑なSELECTのテーブルfooのコンテンツを多数の結合で置き換えます):

BEGIN TRAN; 
TRUNCATE TABLE foo; 
INSERT INTO foo SELECT...; 
COMMIT;

手順2(テーブルfooからの読み取り):

SET TRANSACTION ISOLATION LEVEL SNAPSHOT; 
SELECT * FROM foo;

Procedure2の実行中にProcedure1が実行されている場合、Procedure2は、Procedure1が終了するまで(sp_WhoIsActiveに応じて)LCK_M_SCH_S待機で待機します。そして、Procedure2が完了すると、次の例外が発生します。

このトランザクションの開始以降、ステートメントによってアクセスされたオブジェクトが別の同時トランザクションのDDLステートメントによって変更されたため、データベース 'DatabaseName'でスナップショット分離トランザクションが失敗しました。メタデータはバージョン管理されていないため、許可されません。メタデータへの同時更新は、スナップショット分離と混在している場合、不整合を引き起こす可能性があります。

ただし、Microsoftでは、スナップショット分離では許可されていないDDLステートメントとしてTRUNCATEをリストしていません。http://msdn.microsoft.com/en-us/library/bb933783.aspx

手順2がTRUNCATEの前にテーブルから最も最近コミットされたデータをすぐに返すか、または手順1によって保持されてから、テーブル。手伝ってくれますか?


代わりにDELETE FROM fooを使用できますか?それはスキーマロックを配置しません。
SqlACID 2014年

DELETE FROMは確かに私がこれを回避する方法です。エラーが発生する理由にも興味があります(Procedure1が戻った後でのみ)。
マークフリーマン

回答:


19

リスト'DDL'されている操作のリストは包括的でTRUNCATE TABLEはありません(そのリストからの省略のみではありません)。SQL Serverの問題であるかどうかTRUNCATE TABLEDMLまたはDDL議論の両側に説得力のある例があり、Books Onlineに双方向のエントリがある。

スナップショット分離トランザクションの観点から、TRUNCATEは必須品質有するとるSch-Mロックブロックを説明する(なぜなら、RCSI及びSI依然として取得のSch-Sロック)。また、内部メタデータバージョン(内部の理由*)をバンプして、エラー3961を発生させます。

ですから、あなたが見ている振る舞いは予期されたものであり、十分に文書化されていません。

* TRUNCATE TABLEの現在の実装では、行バージョンは生成されません。メタデータバージョンのバンピングは、正しい動作を保証する最も簡単な方法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.