TINGKAT ISOLASI TRANSAKSI vs. SNAPSHOT vs. TRUNCATE?

10

Saya berharap seseorang dapat menjelaskan perilaku ini yang saya tidak harapkan tentang isolasi SNAPSHOT vs TRUNCATE.

Basis Data: Izinkan Isolasi Snapshot = Benar; Dibaca Dibidik, Snapshot Aktif = Salah.

Procedure1 (Mengganti konten table foo dari SELECT kompleks yang sudah berjalan lama dengan banyak gabungan):

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

Prosedur2 (Dibaca dari tabel foo):

SET TRANSACTION ISOLATION LEVEL SNAPSHOT; 
SELECT * FROM foo;

Jika Prosedure1 sedang berjalan ketika Prosedure2 dijalankan, Prosedure2 ditunda dengan menunggu LCK_M_SCH_S (sesuai dengan sp_WhoIsActive) hingga Procedure1 selesai. Dan ketika Prosedur2 selesai, itu menimbulkan pengecualian ini:

Transaksi isolasi snapshot gagal dalam database 'DatabaseName' karena objek yang diakses oleh pernyataan telah dimodifikasi oleh pernyataan DDL dalam transaksi bersamaan lainnya sejak awal transaksi ini. Itu tidak diizinkan karena metadata tidak diversi. Pembaruan bersamaan untuk metadata dapat menyebabkan inkonsistensi jika dicampur dengan isolasi snapshot.

Namun, Microsoft tidak mencantumkan TRUNCATE sebagai pernyataan DDL yang tidak diizinkan di bawah isolasi SNAPSHOT: http://msdn.microsoft.com/en-us/library/bb933783.aspx

Jelas saya tidak memahami sesuatu dengan benar, seperti yang saya harapkan kasus terbaik dari Prosedur 2 segera mengembalikan data yang paling baru dilakukan dari tabel sebelum TRUNCATE atau kasus terburuk yang ditahan oleh Procedure1 dan kemudian mengembalikan konten baru meja. Bisakah kamu menolong?

Mark Freeman
sumber
Bisakah Anda menggunakan DELETE FROM foo? Itu tidak akan menempatkan kunci skema.
SqlACID
HAPUS DARI memang cara saya mengatasi hal ini. Saya juga tertarik pada mengapa saya mendapatkan kesalahan (dan hanya setelah Prosedure1 dikembalikan).
Mark Freeman

Jawaban:

19

Daftar 'DDL'operasi yang tercantum tidak komprehensif (dan TRUNCATE TABLEbukan satu-satunya penghilangan dari daftar itu). Apakah TRUNCATE TABLEini DMLatau DDLadalah pertanyaan penuh di SQL Server, dengan contoh-contoh persuasif di kedua sisi perdebatan, dan entri kedua cara di buku Online.

Dari sudut pandang transaksi isolasi snapshot, truncate memiliki kualitas penting dari mengambil Sch-Mkunci , yang menjelaskan pemblokiran (karena RCSIdan SImasih memperoleh Sch-Skunci ); dan itu juga menabrak versi metadata internal (karena alasan internal *) mengakibatkan kesalahan 3961.

Jadi, perilaku yang Anda lihat diharapkan, tidak didokumentasikan dengan baik.

* Implementasi TRUNCATE TABLE saat ini tidak menghasilkan versi baris. Membenturkan versi metadata adalah cara paling sederhana untuk memastikan perilaku yang benar.

Paul White 9
sumber