ฉันหวังว่าจะมีใครบางคนแสดงความเข้าใจบางอย่างเกี่ยวกับพฤติกรรมนี้ซึ่งฉันไม่ได้คาดหวังเกี่ยวกับการแยก SNAPSHOT กับ TRUNCATE
ฐานข้อมูล: อนุญาตการแยก Snapshot = True; Is Snapshot On Read ที่ได้รับการยอมรับ = False
ขั้นตอนที่ 1 (แทนที่เนื้อหาของ table foo จาก SELECT ที่ซับซ้อนที่รันเป็นเวลานานด้วยการรวมจำนวนมาก):
BEGIN TRAN;
TRUNCATE TABLE foo;
INSERT INTO foo SELECT...;
COMMIT;
ขั้นตอนที่ 2 (อ่านจากตาราง foo):
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT * FROM foo;
หากโพรซีเดอร์ 1 กำลังรันในขณะที่โพรซีเดอร์ 2 ถูกเรียกใช้งานโพรซีเดอร์ 2 จะถูกระงับด้วย LCK_M_SCH_S รอ (ตาม sp_WhoIsActive) จนกระทั่งขั้นตอน 1 เสร็จสิ้น และเมื่อโพรซีเดอร์ 2 เสร็จสิ้นจะทำให้เกิดข้อยกเว้นนี้:
ธุรกรรมแยก Snapshot ล้มเหลวในฐานข้อมูล 'DatabaseName' เนื่องจากวัตถุที่เข้าถึงโดยคำสั่งนั้นได้รับการแก้ไขโดยคำสั่ง DDL ในธุรกรรมอื่นพร้อมกันนับตั้งแต่เริ่มต้นธุรกรรมนี้ ไม่ได้รับอนุญาตเนื่องจากข้อมูลเมตาไม่ได้เป็นเวอร์ชัน การอัปเดตพร้อมกันเป็นข้อมูลเมตาสามารถนำไปสู่ความไม่สอดคล้องกันหากผสมกับการแยกสแนปชอต
อย่างไรก็ตาม Microsoft ไม่ได้แสดงรายการ TRUNCATE เป็นคำสั่ง DDL ที่ไม่ได้รับอนุญาตภายใต้การแยก SNAPSHOT: http://msdn.microsoft.com/en-us/library/bb933783.aspx
เห็นได้ชัดว่าฉันไม่เข้าใจบางสิ่งบางอย่างอย่างถูกต้องเนื่องจากฉันคาดว่ากรณีที่ดีที่สุดของขั้นตอนที่ 2 จะส่งคืนข้อมูลที่ได้รับล่าสุดจากตารางก่อน TRUNCATE หรือกรณีที่เลวร้ายที่สุดของขั้นตอนที่ 1 จากนั้นส่งคืนเนื้อหาใหม่ของ โต๊ะ. คุณช่วยได้ไหม