2013-02-16 12 views
5

हमें हाल ही में कई ग्राहकों से हमारी सेल सर्वर टेबल में से एक में एक साथ आवेषण के साथ एक समस्या का सामना करना पड़ रहा है। मुझे उम्मीद है कि आप लोग हमारी मदद कर सकते हैं।एसक्यूएल सर्वर - एकाधिक ग्राहकों से तालिका में एक साथ सम्मिलित करें - चेक सीमा और ब्लॉक

हम लेनदेन करने के लिए संग्रहीत प्रक्रिया का उपयोग कर रहे हैं। उस संग्रहित प्रक्रिया में, प्रत्येक लेनदेन के लिए, हम अब तक कुल बिक्री की गणना करते हैं। यदि कुल बिक्री सेट सीमा से कम है, तो लेनदेन की अनुमति होगी। अन्यथा, लेनदेन से इनकार कर दिया जाएगा।

यह कई बार ठीक काम करता है। लेकिन, कभी-कभी जब कई ग्राहक एक ही समय में लेनदेन करने की कोशिश कर रहे होते हैं, तो दोनों लेनदेन के रूप में सीमा जांच विफल हो रही है।

क्या आप लोग सुझाव दे सकते हैं कि हम हर समय सीमा को प्रभावी रूप से कैसे लागू कर सकते हैं? क्या ऐसा करने का कोई बेहतर तरीका है?

धन्यवाद!

+1

कृपया अपनी तालिका संरचना और उदाहरण डेटा प्रदान करें। क्या सभी लेनदेन के लिए निर्धारित सीमा स्थिर है? –

+0

एक झुकाव के रूप में, यदि आप संग्रहित प्रक्रिया को बहुत तेज़ी से चलाते हैं तो समस्या हल हो सकती है। एक 100 एमएमएस संग्रहीत प्रक्रिया टकराव के साथ बहुत दुर्लभ होगा। यदि आप क्वेरी और टेबल परिभाषा पोस्ट करते हैं, तो हम एक इंडेक्स का सुझाव दे सकते हैं जो कुल गणना को बहुत तेज बनाता है। – Andomar

+0

कृपया तालिका संरचना पाएं। प्रत्येक betnumber के लिए इस राशि (हिस्सेदारी) में 1000 से अधिक नहीं होना चाहिए। यह 1000 सीमा किसी अन्य तालिका में संग्रहीत है। \t [SlipID] [bigint] पहचान (1,1), शून्य नहीं \t [TillID] [int] नहीं NULL, \t [बारकोड] [varchar] (30) नहीं NULL, \t [GamingDate] [तारीख] नहीं शून्य, \t [DrawID] [int] नहीं NULL, \t [BetNumber] [tinyint] नहीं NULL, \t [CurrencyID] [int] नहीं NULL, \t [स्टेक] [दशमलव] (9, 2) नहीं NULL , \t \t [स्लिपटाइम] [डेटाटाइम] न्यूल, – sammy

उत्तर

5

मुझे नहीं लगता कि यह घोषणात्मक रूप से करना संभव है।

सभी आवेषण संग्रहीत प्रक्रिया के माध्यम से जाने के लिए गारंटी रहे हैं और SaleValue अपडेट एक बार तो नहीं डाला जाता है निम्नलिखित काम करना चाहिए (मैं मेज और स्तंभ नाम से बना के रूप में इन प्रारंभिक प्रश्न में आपूर्ति नहीं कर रहे थे)

DECLARE @SumSaleValue MONEY 

BEGIN TRAN 

SELECT @SumSaleValue = SUM(SaleValue) 
FROM dbo.Orders WITH (UPDLOCK, HOLDLOCK) 
WHERE TransactionId = @TransactionId 

IF @SumSaleValue > 1000 
    BEGIN 
    RAISERROR('Cannot do insert as total would exceed order limit',16,1); 
    ROLLBACK; 
    RETURN; 
    END 

/*Code for INSERT goes here*/ 

COMMIT 

HOLDLOCK सीरियलज़ेबल सेमेन्टिक्स देता है और TransactionId से मेल खाने वाली पूरी श्रृंखला को लॉक करता है और UPDLOCK समान समेकित लेन-देन को रोकता है, जिससे डेडलॉक्स का खतरा कम हो जाता है।

TransactionId,SaleValue पर एक सूचकांक इस क्वेरी का समर्थन करने के लिए सबसे अच्छा होगा।

+1

+1 चालाक! हो सकता है कि थोड़ा सा चालाक हो, क्योंकि यह कोड संपादित करने वाले किसी के लिए बार बढ़ाता है। प्रक्रिया रिटर्न से पहले लेनदेन को बंद करना एक अच्छा विचार हो सकता है। – Andomar

+0

@Andomar - धन्यवाद। भूल गए! –

+0

धन्यवाद मार्टिन! इससे मदद मिली ... हालांकि, हमने प्रत्येक लेनदेन के लिए कुल मूल्य प्लस या माइनस के साथ सारांश सारणी बनाने के लिए आगे बढ़े।साथ ही, बिक्री सारणी बहुत बड़ी है और कुल योग की गणना करने के लिए तालिका से पूछताछ करने में हर बार समय लगता है क्योंकि बहुत से आवेषण और अनुक्रमणिका बहुत तेजी से विभाजित हो जाते हैं .. इसलिए, हमने उस सारांश तालिका का निर्णय लिया ... अब तक, इसकी मदद ... धन्यवाद! – sammy

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