2009-11-16 10 views
6

पर वापस लौटें मुझे वास्तव में मेरे कोल्डफ्यूजन एप्लिकेशन (एमएस एसक्यूएल 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> 

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

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

+0

क्या आपके पास अपने अपडेट ऑपरेशन की सुरक्षा के लिए '' है? इस तरह सभी समेकन मुद्दों को दूर जाना चाहिए। – Tomalak

+0

अद्यतन cftransaction का हिस्सा है। मुझे यकीन नहीं है कि एक सीएफएलॉक की जरूरत है, नहीं? –

+0

एक cftransaction केवल एक त्रुटि होने पर ही जारी किए गए प्रत्येक SQL कथन को वापस रोल करता है। यह कोड के उस खंड को लॉक नहीं करता है। – Tomalak

उत्तर

12

डेटा का चयन करने के लिए एक सामान्य तालिका अभिव्यक्ति का उपयोग करें, फिर अद्यतन दिनांक से सीटीई और आउटपुट अपडेट करें।

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; 
+0

त्वरित उत्तर के लिए धन्यवाद। मुझे अभी एहसास हुआ है, मुझे केवल 3 आइटम को चुनिंदा क्वेरी से वापस करने की ज़रूरत है, न केवल item_id। यह आपके जवाब को कैसे बदल देगा? –

+0

OUTPUT inserted.item_id, inserted.field2, inserted.field3 –

+0

ठीक है, इसलिए मुझे इस कोड को एक नई संग्रहित प्रो में छोड़ने में सक्षम होना चाहिए और स्पष्ट रूप से # varname # कोल्डफ्यूजन स्टाइल वर्र्स को @varname संग्रहित प्रो वर्र्स में बदलना चाहिए और सभी होना चाहिए अच्छा, नहीं? –

2

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

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 

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

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

+0

हां, लेकिन अद्यतन के अंदर चयन डालने का मुद्दा यह है कि मुझे इस लेनदेन के हिस्से के रूप में चयन क्वेरी की सामग्री को वापस करने की आवश्यकता है। –

+0

आपको होल्डॉक की आवश्यकता क्यों है? क्या आप एक अद्यतन कर रहे हैं जब भी लॉक आयोजित किया जाएगा? – erikkallen

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