2009-01-30 4 views
16

मैं की तरह एक परमाणु लेन-देन लागू करना चाहते हैं निम्नलिखित:मुझे कौन से लॉक संकेतों का उपयोग करना चाहिए (टी-एसक्यूएल)?

BEGIN TRAN A 

SELECT id 
FROM Inventory 
WITH (???) 
WHERE material_id = 25 AND quantity > 10 

/* 
Process some things using the inventory record and 
eventually write some updates that are dependent on the fact that 
that specific inventory record had sufficient quantity (greater than 10). 
*/ 

COMMIT TRAN A 

समस्या देखते हैं कि अन्य लेन-देन हो रहा है कि हमारे सूची से मात्रा उपभोग करते हैं, समय के बीच इतना है कि रिकॉर्ड चयन किया जाता है और अद्यतन लिखा जाता है लेनदेन में ए रिकॉर्ड एक अमान्य चयन बन सकता है क्योंकि यह WHERE खंड में दहलीज के नीचे मात्रा कम हो सकती है।

तो प्रश्न यह है कि मैंने अपने अद्यतनों को पूरा करने और लेनदेन करने से पहले चयनित सूची रिकॉर्ड को बदलने से रोकने के लिए इन खंडों में लॉकिंग संकेतों का उपयोग करना चाहिए?

संपादित करें: तो जॉन के लिए धन्यवाद, एक अच्छा समाधान लेनदेन अलगाव स्तर को दोहराने के लिए सेट करना प्रतीत होता है। यह सुनिश्चित करेगा कि "कोई अन्य लेन-देन डेटा को संशोधित नहीं कर सकता है जो वर्तमान लेनदेन द्वारा पढ़ा गया है जब तक कि वर्तमान लेनदेन पूरा नहीं हो जाता।"

+0

अच्छा सवाल है ... मैं कुछ कोड पर काम करने जा रहा हूँ कि वास्तव में फिट बैठता है यह मानदंड जल्द ही ... मुझे यह भी एहसास नहीं हुआ कि यह एक मुद्दा था :) –

+0

धन्यवाद एंड्रयू! हाँ यह मेरे लिए हुआ कि एक लेनदेन वास्तव में एक सतत परिणाम नहीं दे रहा है अगर डेटा या लेनदेन का उपयोग कर रहे अनुमानों को बदल रहा है, जबकि यह प्रसंस्करण हो रहा है। – Daniel

उत्तर

11

आप वास्तव में इस लेनदेन अलगाव स्तर की स्थापना के बजाय एक प्रश्न संकेत का उपयोग कर से बेहतर हो सकता है।

पुस्तकें ऑनलाइन से निम्नलिखित संदर्भ अलग-अलग अलगाव स्तरों का विवरण प्रदान करता है।

http://msdn.microsoft.com/en-us/library/ms173763.aspx

यहाँ अच्छा लेख है कि एसक्यूएल सर्वर में व्यवहार ताला लगा के विभिन्न प्रकार बताते हैं और उदाहरण भी प्रदान करता है।

http://www.sqlteam.com/article/introduction-to-locking-in-sql-server

+0

समस्या को कैसे पढ़ते हैं तो क्या आप दोहराए गए रीड अलगाव स्तर का उपयोग करने का सुझाव देंगे? – Daniel

+0

हां यह निश्चित रूप से काम करेगा। भविष्य के संदर्भ के लिए, आप SQL अलगाव के भीतर उपलब्ध अन्य अलगाव स्तरों के बारे में स्वयं को शिक्षित करना चाहेंगे, जो पंक्ति संस्करण का उपयोग करते हैं। यह काफी कठिन पढ़ा गया है लेकिन मूल्यवान ज्ञान है, http://msdn.microsoft.com/en-us/library/ms345124.aspx –

+0

अच्छा जवाब - हम अपने स्टैक ओवरफ्लो डीबी की स्थापना करते समय सभी अलगाव स्तर दस्तावेज़ों के माध्यम से गए। –

0

मेरा मानना ​​है कि यह अपडॉक होगा।

http://www.devx.com/tips/Tip/13134

+0

ध्यान रखें कि SQL सर्वर 2005 और उसके बाद में लॉकिंग इस तरह से नहीं है। लेख काफी दिनांकित है। –

+0

मैं SQL सर्वर 2005 का उपयोग कर रहा हूं। – Daniel

0
UPDLOCK साथ

, HOLDLOCK

+1

होल्डॉक की आवश्यकता क्यों है? – Daniel

+1

यह सुनिश्चित करने के लिए कि कोई अन्य प्रक्रिया इसे भी पढ़ न सके और यह ट्रैन – SQLMenace

+1

UPDLOCK की अवधि के लिए इसे बनाए रखेगा – gbn

2

table hints

WITH (HOLDLOCK) अन्य पाठकों की अनुमति देता है। अपड्लॉक जैसा कहीं और सुझाया गया है अनन्य है।

होल्डॉक अन्य अपडेट को रोक देगा लेकिन वे बाद में अपडेट किए गए डेटा का उपयोग कर सकते हैं।

UPDLOCK जब भी आप प्रतिबद्ध या रोलबैक तक डेटा को पढ़ने से रोकते हैं।

क्या आपने sp_getapplock पर देखा है? यह यूपीडीएलके ब्लॉकिंग

संपादित करें: समस्या मुख्य रूप से इस कोड में 2 अलग-अलग सत्रों में चल रही है, इस समस्या को क्रमबद्ध करने के लिए आपको अनुमति देगा (यदि यह एकमात्र अपडेट बिट है)। होल्डलोक या REPEATABLE_READ के साथ, डेटा को पहले सत्र अपडेट से पहले दूसरे सत्र में पढ़ा जाएगा। अपडॉक के साथ, कोई भी सत्र किसी भी सत्र में डेटा नहीं पढ़ सकता है।

+0

समस्या सीज़ियन बी को डेटा पढ़ने से रोकने की कोशिश नहीं कर रही है जबकि सत्र ए लेनदेन को निष्पादित कर रहा है। समस्या यह है कि सत्र बी को लिखने से पंक्ति में रखना है कि सत्र ए का लेनदेन इसकी गणना में उपयोग कर रहा है, ताकि स्थिर डेटा का उपयोग करने से गणना को रोका जा सके। – Daniel

+0

तब होल्डलॉक। पढ़ने की अनुमति देता है लेकिन लिख नहीं है। या सभी डेटा स्थानीय वर्र्स/टेबल चर में लोड करें – gbn

2

MSSQL:

SELECT id 
FROM Inventory (UPDLOCK) 
WHERE material_id = 25 AND quantity > 10; 

http://www.devx.com/tips/Tip/13134 



आप PostgreSQL के साथ रुचि रखते हैं कोई मौका द्वारा:

SELECT id 
FROM Inventory  
WHERE material_id = 25 AND quantity > 10 
FOR UPDATE; 
संबंधित मुद्दे