Mengapa kueri ini menyebabkan jalan buntu?

11

Mengapa kueri ini menyebabkan jalan buntu?

UPDATE TOP(1) system_Queue SET
  [StatusID] = 2,
  @ID = InternalID
WHERE InternalID IN (
    SELECT TOP 1 
      InternalID FROM system_Queue
    WHERE IsOutGoing = @IsOutGoing AND StatusID = 1
ORDER BY MessageID ASC, InternalID ASC)

Deadlock graph menambahkan:

<keylock hobtid="72057594236436480" dbid="9" objectname="Z.dbo.system_Queue" indexname="PK_system_Queue" id="lock5b25cc80" mode="X" associatedObjectId="72057594236436480">
    <owner-list>
     <owner id="processc6fe40" mode="X"/>
    </owner-list>
    <waiter-list>
     <waiter id="processc7b8e8" mode="S" requestType="wait"/>
    </waiter-list>
   </keylock>
   <keylock hobtid="72057594405453824" dbid="9" objectname="Z.dbo.system_Queue" indexname="IX_system_Queue_DirectionByStatus" id="lock48cf3180" mode="S" associatedObjectId="72057594405453824">
    <owner-list>
     <owner id="processc7b8e8" mode="S"/>
    </owner-list>
    <waiter-list>
     <waiter id="processc6fe40" mode="X" requestType="wait"/>
    </waiter-list>
   </keylock>

TAMBAH:

Terima kasih Sankar untuk artikel yang memiliki solusi bagaimana menghindari kebuntuan jenis ini:

  • menghilangkan kolom yang tidak perlu dari proyeksi pembaca sehingga ia tidak perlu mencari indeks berkerumun
  • tambahkan kolom yang diperlukan sebagai kolom yang terkandung ke indeks non-cluster untuk membuat indeks mencakup, lagi sehingga pembaca tidak harus mencari indeks clustered
  • hindari pembaruan yang harus mempertahankan indeks non-cluster
garik
sumber
versi apa dari platform db yang Anda gunakan? apa tingkat isolasi trx (atau konkurensi) default? Indeks apa yang ada pada tabel system_Queue saat ini?
SQLRockstar
@SQLRockstar bagian dari deadlock graph ditambahkan, sql server 2008
garik
@SQLRockstar IX_system_Queue_DirectionByStatus indeks oleh IsOutGoing dan StatusID.
garik

Jawaban:

13

Sepertinya saya mencoba melakukan SELECT dan UPDATE dalam pernyataan yang sama dan ke tabel yang sama.

SELECT memegang kunci bersama pada nilai-nilai di dalam indeks IX_system_Queue_DirectionByStatus, dan kebutuhan UPDATE untuk kunci-kunci itu akan dirilis sebelum itu bisa mendapatkan kunci eksklusif yang akan memperbarui kunci utama (yang saya kira akan dikelompokkan dan juga bagian dari Nilai kunci IX_system_Queue_DirectionByStatus).

Lagi pula, tebakan saya adalah permintaan ini hanya akan berhasil pada kesempatan langka bahwa nilai indeks yang dipilih dan diperbarui tidak bertentangan. Apakah ini menemui jalan buntu setiap kali Anda mengeksekusi (saya berasumsi akan demikian).

Berikut ini tautan yang menjelaskan kebuntuan dengan lebih terperinci: http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx

SQLRockstar
sumber
Bingo! Terima kasih. Situasi yang benar-benar aneh untuk kebuntuan yang pernah saya lihat. Terimakasih untuk jawaban.
garik