2011-11-01 17 views
5

मैं चाहता हूँ करने के लिए:पंक्तियाँ और एक ही पंक्तियां अपडेट एसक्यूएल चुनें

    प्रसंस्करण के लिए एक मेज जहां झंडा = 0
  1. कुछ काम करें एक दूसरी तालिका पर इन से मूल्यों का उपयोग करने से
  2. चुनें एन पंक्तियों एन पंक्तियों
  3. अद्यतन इन एन पंक्तियों और ध्वज सेट = 1

मैं समानांतर प्रक्रियाएं एक साथ यह एक ही काम कर रही है, और मैं यह सुनिश्चित करें कि सभी अद्वितीय पंक्तियों पर काम शुरू कर चाहते हैं। मैं यह कैसे सुनिश्चित करूं?

उत्तर

5

मुझे लगता है कि आप SQL सर्वर (टैग की वजह से) चल रहे हैं, यदि नहीं तो मेरा उत्तर लागू नहीं है। अकेले लॉक करना पर्याप्त नहीं है। यदि आप डेटाबेस रिकॉर्ड लॉकिंग का उपयोग करते हैं तो एसक्यूएल सर्वर लॉक की गई पंक्ति तक पहुंचने की कोशिश कर रहे अन्य प्रक्रियाओं को अवरुद्ध कर देगा और असल में आप एक समय में केवल एक पंक्ति को संभालेंगे। आपके लिए समाधान रीडपैस्ट संकेत के साथ पंक्ति लॉकिंग को जोड़ना है ताकि किसी और द्वारा लॉक की गई पंक्तियां छोड़ी जाएंगी। यहां प्रत्येक प्रक्रिया कदम उठाएं:

  1. प्रसंस्करण के लिए अगले खुला पंक्ति चुनें और ताला यह
  2. काम
  3. अद्यतन पंक्ति और अंत लेनदेन करना

select top 1 id, ... from TheTable with (updlock, readpast) where flag = 0

//do the work now

update TheTable set flag = 1 where id=<previously retrieved id>

अच्छी बात यह है कि अगली अनलॉक पंक्ति का चयन करने और इसे लॉक करने का संचालन परमाणु है इसलिए यह गारंटी देता है कि कोई भी एक ही पंक्ति का चयन करने में सक्षम नहीं होगा।

+0

रीडपैस्ट संकेत चाल करता है, एक अच्छा लेख http://www.mssqltips.com/sqlservertip/1257/processing-data-queues-in-sql-server-with-readpast-and-updlock/ – newbie

+0

SQL 2008 के साथ , आप क्यूई ऑपरेशन को एक कथन में गठबंधन करने के लिए क्वेरी में रीडपेस्ट एचआईएनटी के साथ आउटपुट क्लॉज का उपयोग कर सकते हैं। http://www.sqlservercentral.com/articles/Queue+processing/69653/ – newbie

+0

@newbie हां, आप इसका उपयोग कर सकते हैं संदेशों को लॉक और पुनर्प्राप्त करने के लिए आउटपुट और इसे एक ही क्वेरी में संसाधित चिह्नित करें। लेकिन मैं एकल संदेश प्रसंस्करण के लिए प्रदर्शन की तुलना कर रहा हूं और दो प्रश्नों की तुलना में कोई लाभ नहीं है (पहले चुनें और फिर अपडेट करें)। असल में बहु-थ्रेडेड थ्रूपुट OUTPUT क्वेरी का उपयोग करते समय थोड़ा कम था। शायद बैच प्रोसेसिंग आउटपुट क्लॉज में तेजी से होगा, लेकिन एकल संदेशों के लिए यह नहीं है। – nightwatch

0

एक तरीका यह है कि एक मास्टर प्रोग्राम बाल धागे को सेगमेंट से बाहर निकालना है।

तालिका को लॉक करने का एक और तरीका है, CEIL(N/#processes) पंक्तियां जहां ध्वज = 0, ध्वज को 2 पर अपडेट करें, फिर लॉक को छोड़ दें। फिर अगली प्रक्रिया लॉक हो जाने के बाद जारी रहेगी, और चूंकि ध्वज = 2 यह उन पंक्तियों को नहीं मिलेगा।

आपके पास टेबल को लॉक करने के दो तरीके हैं - आप या तो पूरी चीज को लॉक कर सकते हैं या चयन कर सकते हैं ... एक सीमा के साथ अद्यतन के लिए (बहुत अधिक पंक्तियां नहीं प्राप्त करने के लिए)। देखें: SELECT FOR UPDATE with SQL Server

फ्लैग को 2 पर सेट करने से भी बेहतर है, ध्वज को process_id पर सेट किया गया है। तो आपको केवल संख्याओं को वितरित करने के लिए सभी पंक्तियों को अपडेट करना है, फिर प्रक्रिया को काम करने दें, प्रत्येक केवल अपनी पंक्तियों की जांच करें।

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