2009-06-02 12 views
36

मेरे पास ऑर्डर कतार है जिसे संग्रहीत प्रक्रिया के माध्यम से एकाधिक ऑर्डर प्रोसेसर द्वारा एक्सेस किया जाता है। प्रत्येक प्रोसेसर एक अद्वितीय आईडी में गुजरता है जिसका उपयोग अगले 20 ऑर्डर को अपने स्वयं के उपयोग के लिए लॉक करने के लिए किया जाता है। संग्रहीत प्रक्रिया तब इन रिकॉर्डों को ऑर्डर प्रोसेसर पर काम करने के लिए लौटाती है।एसक्यूएल सर्वर प्रक्रिया कतार रेस कंडीशन

ऐसे मामले हैं जहां एकाधिक प्रोसेसर एक ही 'ऑर्डरटेबल' रिकॉर्ड पुनर्प्राप्त करने में सक्षम हैं, जिस बिंदु पर वे एक साथ काम करने की कोशिश करते हैं। अंत में प्रक्रिया में बाद में त्रुटियों को फेंकने के परिणामस्वरूप।

मेरा अगला कार्यवाही प्रत्येक प्रोसेसर को सभी उपलब्ध ऑर्डर ले जाने और प्रोसेसर को रॉबिन के चारों ओर ले जाने की अनुमति देने के लिए है, लेकिन मैं बस कोड थ्रेड के इस अनुभाग को सुरक्षित करने की उम्मीद कर रहा था और प्रोसेसर को जब भी चाहें रिकॉर्ड प्राप्त करने की अनुमति देता था।

तो स्पष्ट रूप से - कोई विचार क्यों मुझे इस दौड़ की स्थिति का सामना करना पड़ रहा है और मैं समस्या को कैसे हल कर सकता हूं।

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 "(एसक्यूएल में Mutexs) अपनी ताले बनाने के द्वारा सहायता करना कन्करेंसी"

: जाहिर है वह पता है कि कैसे करना चाहता है इस संग्रहीत प्रक्रिया को फिर से लिखने के लिए ताकि परिणामस्वरूप दो प्रोसेसर एक ही रिकॉर्ड को संसाधित न करें। – Welbog

उत्तर

48

संपादित करें: "Processing Data Queues in SQL Server with READPAST and UPDLOCK":

मैं अपने जवाब की जांच करने के googled। यह वर्षों से मैंने इस समाधान के साथ पढ़ा और खेला है।

मूल:

आप READPAST संकेत का उपयोग करते हैं, तो बंद कर दिया पंक्तियों को छोड़ दिया जाता है। आपने ROWLOCK का उपयोग किया है, इसलिए आपको लॉक एस्केलेशन से बचना चाहिए। जैसा कि मैंने पाया, आपको भी अपडॉक की आवश्यकता है।

तो की प्रक्रिया 1 ताले 20 पंक्तियाँ, प्रक्रिया 2 ले जाएगा अगले 20, प्रक्रिया 3 पंक्तियों 60 करने के लिए 41 लेता है आदि

अद्यतन भी इस तरह लिखा जा सकता है:

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

ताज़ा अक्टूबर 2011

यदि आपको एक चयन में एक चयन और अद्यतन की आवश्यकता है तो यह OUTPUT खंड के साथ अधिक सुंदरता से किया जा सकता है।

+0

दिलचस्प ... मैं इसे –

+0

कोशिश करूँगा अतिरिक्त संकेत जोड़कर वास्तव में मदद मिली। कोई और डुप्लीकेट नहीं। धन्यवाद। –

+0

मुझे पता है कि यह पुराना है, लेकिन अपडेट करने के लिए पंक्तियों को पढ़ने के दौरान अद्यतन ताले (बदले गए ताले के बजाए) को 'अद्यतन' कथन में 'अपड्लॉक' संकेत है? दूसरे शब्दों में, यदि आप 'UPDLOCK' का उपयोग नहीं करते हैं, तो क्या एक पंक्ति की स्थिति के लिए संभव है और एक ही पंक्तियों का चयन करने के लिए दो अद्यतन विवरण? –

6

आप सेवा ब्रोकर का उपयोग कर सकते हैं। इसके अलावा आप अपनी पंक्तियों के लिए उपयोग क्रमानुसार करने sp_getapplock उपयोग कर सकते हैं - कि दौड़ की स्थिति को खत्म होगा: http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006/06/30/855.aspx

संबंधित मुद्दे