UPDATE heap table -> Deadlock pada RID

8

Saya menyiapkan test case untuk membuktikan skenario jalan buntu tertentu dan memerlukan beberapa wawasan tentang apa yang sedang terjadi. Saya memiliki tabel heap, disebut HeapTable. Tabel ini diperbarui oleh 2 transaksi secara simultan.

Transaksi 1:

BEGIN TRAN

UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';

WAITFOR DELAY '00:00:15';

UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';

ROLLBACK TRANSACTION

Transaksi 2:

BEGIN TRAN

UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';

ROLLBACK TRAN

Saya mematikan transaksi 1 terlebih dahulu, diikuti dengan transaksi 2. Seperti yang diharapkan transaksi 1 akan mengklaim beberapa kunci eksklusif, bersama dengan beberapa yang eksklusif maksud. Transaksi 2 akan masuk dan meminta kunci Pembaruan pada RID yang sama:

spid dbid   ObjId       IndId   Type    Resource     Mode   Status
55    5     711673583   0       RID     1:24336:10   X      GRANT
57    5     711673583   0       RID     1:24336:10   U      WAIT

Saya agak terkejut melihat transaksi kedua meminta kunci pembaruan pada RID yang sama, karena saya pikir ini menunjuk ke satu catatan & kedua pernyataan pembaruan menangani data yang berbeda. Saya malah mengharapkan konflik di tingkat halaman sebagai gantinya.

Ketika pembaruan kedua transaksi 1 tendangan dalam transaksi 2 akan dilihat sebagai korban kebuntuan yang mengakibatkan kemunduran transaksi 2 & penyelesaian transaksi 1.

Dapatkah seseorang menjelaskan kepada saya mengapa transaksi kedua akan membutuhkan kunci pembaruan pada RID yang sama meskipun memperbarui catatan yang berbeda?

Saya tahu cara memperbaikinya (misalnya dengan indeks). Saya tidak mencari perbaikan, saya benar-benar mencari penjelasan mengapa 2 Pembaruan menangani catatan yang berbeda di tumpukan ingin mengunci RID yang sama. Saya menggunakan isolasi yang dilakukan baca. Tidak ada indeks nonclustered di atas meja.

Jens
sumber

Jawaban:

18

Tanpa indeks aktif FirstName, SQL Server harus memeriksa setiap baris untuk melihat apakah memenuhi syarat untuk UPDATE.

Dibutuhkan Ukunci pembaruan saat membaca setiap baris untuk mencegah skenario kebuntuan yang umum. Itu bisa mengambil Skunci bersama , tapi itu masih akan diblokir oleh Xkunci eksklusif yang dipegang oleh transaksi pertama.

Paul White 9
sumber