Bu sorgu neden bir kilitlenmeye neden oluyor?


11

Bu sorgu neden bir kilitlenmeye neden oluyor?

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)

Kilitlenme grafiği eklendi:

<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>

KATMA:

Bu tür çıkmazlardan nasıl kaçınılacağına dair çözümleri olan makale için Sankar'a teşekkür ederiz :

  • kümelenmiş dizini aramak zorunda kalmaması için gereksiz sütunları okuyucunun izdüşümünden kaldırın
  • dizin kaplamasını yapmak için gerekli sütunları kümelenmemiş dizine içerilen sütunlar olarak ekleyin, böylece okuyucunun kümelenmiş dizine bakmaması gerekir
  • kümelenmemiş dizini korumak zorunda olan güncelleştirmelerden kaçının

hangi db platformunun hangi sürümünü kullanıyorsunuz? varsayılan trx yalıtım (veya eşzamanlılık) düzeyi nedir? Şu anda system_Queue tablosunda hangi dizinler var?
SQLRockstar

@SlockRockstar deadlock grafiğinin bir parçası eklendi, sql server 2008
garik

@SQLRockstar IX_system_Queue_DirectionByStatus dizini IsOutGoing ve StatusID tarafından.
garik

Yanıtlar:


13

Bana aynı ifadede ve aynı tabloda bir SELECT ve UPDATE yapmaya çalışıyormuşsunuz gibi geliyor.

SELECT, IX_system_Queue_DirectionByStatus endeksi içindeki değerlerde paylaşılan bir kilit tutuyor ve UPDATE, birincil anahtarı güncelleyecek olan özel kilidini alabilmek için bu kilitlerin serbest bırakılmadan önce serbest bırakılması gerekiyor. IX_system_Queue_DirectionByStatus anahtar değeri).

Her neyse, tahminim bu sorgu sadece seçtiği ve güncellediği indeks değerlerinin çakışmadığı nadir bir fırsatta başarılı olacaktır. Her yürüttüğünüzde kilitlenme var mı (olacağını varsayıyorum).

Kilitlenmeleri daha ayrıntılı olarak açıklayan bir bağlantı: http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx


Bingo! Teşekkür ederim. Gördüğüm çıkmaz için gerçekten garip bir durumdu. Cevabın için teşekkür ederim.
garik

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.