2009-06-02 14 views
36

Kayıtlı bir yordamla birden çok sipariş işlemcisi tarafından erişilen bir sipariş kuyruğum var. Her işlemci, sonraki 20 siparişi kendi kullanımı için kilitlemek için kullanılan benzersiz bir kimlikten geçer. Saklanan prosedür daha sonra, bu kayıtları, üzerinde harekete geçecek olan sipariş işlemcisine geri gönderir.SQL Server İşlem Kuyruk Yarışı Koşulu

çoklu işlemcilerin, aynı anda üzerinde çalıştıkları aynı noktada 'OrderTable' kaydı'u alabilecekleri durumlar vardır. Bu sonuçta süreçte daha sonra atılan hatalarla sonuçlanır.

Bir sonraki adımım, her bir işlemcinin tüm mevcut siparişleri almasına ve yalnızca işlemcileri dolaştırmasına izin vermektir; ancak bu kod parçasının bu bölümünü güvenli hale getirmeyi ve işlemcilerin istedikleri zaman kayıtları almalarını sağlamayı umuyorum.

Açıkça - Neden bu yarış koşulunu yaşıyorum ve sorunu nasıl çözebilirim.

BEGIN TRAN 
    UPDATE OrderTable WITH (ROWLOCK) 
    SET  ProcessorID = @PROCID 
    WHERE OrderID IN (SELECT TOP (20) 
             OrderID 
           FROM OrderTable WITH (ROWLOCK) 
           WHERE ProcessorID = 0) 
COMMIT TRAN 


SELECT OrderID, ProcessorID, etc... 
FROM OrderTable 
WHERE ProcessorID = @PROCID 
+4

@Keltex "(SQL Mutexs) Kendi Kilitler oluşturarak Yardım eşzamanlılık"

: Açıkçası o bilmek istiyor Bu saklı yordamı yeniden yazmak için, iki işlemcinin aynı kayıtları/işlemleri işlemesine neden olmaz. – Welbog

cevap

48

Düzenleme: "Processing Data Queues in SQL Server with READPAST and UPDLOCK":

cevabımı kontrol etmek googled. Bu çözümü okuduğum ve oynadığımdan beri yıllar geçti. Orijinal

:

Eğer READPAST ipucu kullanırsanız, o zaman kilitli satırlar atlanır. ROWLOCK'u kullandınız, bu yüzden kilit yükseltme işleminden kaçınmalısınız. Ayrıca öğrendiğim gibi UPDLOCK'a ihtiyacınız var. ,

UPDATE TOP (20) 
    foo 
SET 
    ProcessorID = @PROCID 
FROM 
    OrderTable foo WITH (ROWLOCK, READPAST, UPDLOCK) 
WHERE 
    ProcessorID = 0 

Yenile:

Yani vb

güncelleme de böyle yazılabilir, süreç 3 Satırlar 60 41 alır, 1 kilitler 20 satır, süreç 2 sonraki 20 alacak işlemek Eki 2011

Bir seferde SELECT ve UPDATE'e ihtiyacınız varsa, bu daha fazla OUTPUT yan tümcesi ile yapılabilir.

+0

İlginç ... Bunu bir deneyin vereceğim –

+0

Ek ipuçları gerçekten eklendiğinde yardımcı oldu. Başka kopya yok. Teşekkürler. –

+0

Bunun eski olduğunu biliyorum, ancak güncelleme güncellenmesi için satırları okurken * UPDATE deyiminin güncelleme kilitlerini zorladığını (paylaşılan kilitler yerine) UPDLOCK'un ipucu nedir? Diğer bir deyişle, 'UPDLOCK' kullanmıyorsanız, bir yarış koşulunun bulunması ve iki satırlık ifadenin aynı satırı seçmesi mümkün mü? –