sql - टीएसक्यूएल तो एक लेन-देन में अपडेट करें, फिर SELECT चुनें



tsql stored-procedures (2)

मुझे वास्तव में मेरे कोल्डफ्यूजन एप्लिकेशन में एक क्वेरी में परेशानी हो रही है (एमएस एसक्यूएल 2008 को समर्थित)। मैं इस लेनदेन पर डीबी डेडलॉक त्रुटियों को प्राप्त करता हूं:

<code>
<cftransaction>
   <cfquery name="selectQuery">
      SELECT TOP 20 item_id, field2, field3
      FROM Table1
      WHERE subject_id = #subject_ID# AND lock_field IS NULL AND
            NOT EXISTS (SELECT * FROM Table2 WHERE Table2.user_ID = #user_ID# Table1.item_id = Table2.item_id)
   </cfquery>

   <cfquery name="updateQuery">
      UPDATE Table1
      SET lock_field = 1, locked_by = #user_ID#
      WHERE Table1.item_id IN (#ValueList(selectQuery.item_id#)
   </cfquery>
</cftransaction>
</code>

मूल रूप से, मेरे पास एक टेबल (टेबल 1) है जो प्रतीक्षा वस्तुओं की एक बड़ी कतार का प्रतिनिधित्व करता है। उपयोगकर्ता "चेकआउट" आइटम उन्हें स्कोर देने के लिए केवल एक उपयोगकर्ता के पास एक समय में एक आइटम की जांच हो सकती है मुझे किसी दिए गए उपयोगकर्ता के लिए एक समय में 20 आइटमों के ब्लॉक का अनुरोध करना होगा। उन मदों को पहले से ही चेक नहीं किया जा सकता है और उपयोगकर्ता पहले ही उन्हें पहले नहीं बना सकता है (इसलिए लॉक_फ़ील्ड नल है और चयन में उपलब्ध नहीं है)। एक बार मैंने 20 आइटम आईडी की सूची निर्धारित की है, तो मुझे उन्हें लॉक के रूप में चिह्नित करने के लिए कतार तालिका अपडेट करने की आवश्यकता है ताकि कोई भी उन्हें एक ही समय में जांच न सके। मुझे आइटम_आईड्स की उस सूची को भी वापस करना होगा

मैं सोच रहा था कि यह बेहतर काम कर सकता है अगर मैं इसे एक cftransaction से SQL सर्वर की तरफ एक संग्रहीत proc पर ले जाया गया। मुझे सिर्फ यकीन नहीं है कि अगर cftransaction लॉकिंग किसी तरह हस्तक्षेप कर रहा है मैं टीएसक्यूएल गुरु नहीं हूं, इसलिए कुछ मदद की सराहना की जाएगी।

https://src-bin.com


Answer #1

डेटा का चयन करने के लिए एक सामान्य तालिका अभिव्यक्ति का उपयोग करें, फिर अपॉइंटमेंट कथन से सीटीई और आउटपुट अपडेट करें इस तरह सब कुछ एक ही ऑपरेशन है:

with cte as (
 SELECT TOP 20 item_id, field2, field3 
 FROM Table1 WITH (ROWLOCK, UPDLOCK)
 WHERE subject_id = #subject_ID# 
 AND lock_field IS NULL 
 AND NOT EXISTS (
   SELECT * FROM Table2 
   WHERE Table2.user_ID = #user_ID# AND Table1.item_id = Table2.item_id))
update cte   
 SET lock_field = 1, locked_by = #user_ID# 
 output inserted.item_id;

Answer #2

PHP के बारे में बहुत कुछ जानने (पढ़ने के लिए: कुछ भी नहीं), लेकिन टीएसक्यूएल के साथ कुछ अनुभव होने पर आप अपनी क्वेरी को इस तरह से बदलने पर विचार कर सकते हैं:

update TABLE1 set LOCK_FIELD = 1
output inserted.item_id, inserted.OtherInterestingColumnsGoHere
from (select top 20 item_id from TABLE1(holdlock) ) as a
where a.item_id = table1.item_id

यह सुनिश्चित करना चाहिए कि आपके चयन को अपडेट पूरा होने तक लॉक कर दिया जाएगा।

संपादित करें: मूल प्रश्न के रूप में एक आउटपुट क्लॉज जोड़ा गया, यह भी जानना चाहता था कि कौन से पंक्तियों को अपडेट किया गया था





coldfusion