2016-10-16 49 views
5

इस परिदृश्य की कल्पना करें, मेरे पास ऐसी वेबसाइट है जो उपयोगकर्ताओं को अपनी वस्तुओं को बेचने या विज्ञापनों पर क्लिक करने या जो भी मेरी उपयोगकर्ता तालिका होगी, गतिविधि के साथ क्रेडिट प्राप्त करती है इसक्या मुझे दिए गए परिदृश्य में UPDATE ऑपरेशन में एक साथ अनुरोध के बारे में चिंता करने की आवश्यकता है

users : id , username , credit 
     15 , alex  , 1000 
     16 , jack  , 1500 

की तरह कुछ तो अब उन भुगतान के कुछ प्रकार में अपने क्रेडिट को वापस लेने का अनुरोध कर सकते हैं मेरी तात्पर्य तालिका इस

withdraws : 
id , user_id , amount 
1 , 15  , 500 
2 , 16  , 100 

मैं अपने क्रेडिट से राशि वापस लेने घटाना है की तरह कुछ होगा .. मुझे ट्रिगर के साथ ऐसा करना पसंद है

CREATE TRIGGER withdraw 
    BEFORE INSERT 
    ON withdraws 
    FOR EACH ROW 
BEGIN 

    UPDATE users SET credit = credit-NEW.amount WHERE id = NEW.user_id; 
END $$ 

और यह सुनिश्चित करें उन नहीं कर सकते वापस लेने की प्रक्रिया में नकारात्मक क्रेडिट के साथ खत्म हो मैं इस ट्रिगर होता है (अभिशाप के रूप में अच्छी तरह मैं कोड तर्क में इस की जांच करेंगे)

CREATE TRIGGER update_user 
    BEFORE UPDATE 
    ON users 
    FOR EACH ROW 
BEGIN 

    IF NEW.credit < 0 THEN 
      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'invalid credit error'; 
    END IF; 


END $$ 

अब बनाने के लिए मेरा सवाल यह है कि, क्या यह जानबूझकर संभव है कि कोई व्यक्ति किसी प्रकार की सर्वर त्रुटि को एक ही समय में एकाधिक निकासी अनुरोध भेजता है, और उसके क्रेडिट से अधिक वापस लेता है .... और यदि ऐसा है तो मैं इसे कैसे रोक सकता हूं?

क्या मुझे प्रत्येक वापसी सम्मिलन या इस तरह से कुछ भी पहले उपयोगकर्ता तालिका को लॉक करने की आवश्यकता है?

अद्यतन: अगर im उपयोगकर्ता पंक्ति ताला और पूरे ऑपरेशन के लिए लेन-देन आवरण का उपयोग करने जा ... उचित लगता है, लेकिन कैसे ट्रिगर में फिट बैठता है करता है? मेरा मतलब है कि मुझे लेनदेन शुरू करना है और इसे कोड में समाप्त करना/प्रतिबद्ध करना है (क्योंकि मैं संग्रहीत प्रक्रियाओं से नफरत करता हूं और कभी उनका उपयोग नहीं करता) क्या इसका मतलब है कि मुझे ट्रिगर छोड़ना है और कोड में घटाव भी करना है या किसी भी तरह ट्रिगर होता है विभिन्न प्लेटफार्म/जगह

उत्तर

1

में शुरू/निष्पादन के बावजूद लेनदेन के अंदर मैं इरादे ताले के माध्यम से इसे हल कर दूंगा। मैंने लिखा एक उदाहरण here देखें। ट्रांज़ेक्शन खंड के लाइन 1 से लाइन 5 के साथ-साथ अन्य प्रासंगिक जानकारी के बीच क्या होता है, वहां एक कथा है।

आप स्वाभाविक रूप से है कि उदाहरण की तरह एक incrementor नहीं मिल रहा है। इसके बजाय, आपका कोड जितना तेज़ हो सके उतना तेज़ अपडेट करेगा और कमेट करेगा।

कि कोड सिर्फ एक संग्रहीत proc में कहीं भी हो सकती है। यह हो सकता है और घटना या एक ट्रिगर। डीबी इंजन (जैसे आईएनएनओडीबी) यह सुनिश्चित करने के लिए आपका तंत्र है कि एक ही समय में दो लोग उस LOCK के अंदर नहीं जा सकते हैं। आप इससे संबंधित अपना कोड कैसे लिखते हैं आप पर निर्भर है।

+0

तो मूल रूप से उपयोगकर्ता पंक्ति ताला और पूरे ऑपरेशन के लिए लेन-देन आवरण का उपयोग करें ... उचित लगता है, लेकिन कैसे ट्रिगर में फिट बैठता है करता है?मेरा मतलब है कि मुझे लेनदेन शुरू करना है और इसे कोड में समाप्त करना/प्रतिबद्ध करना है (आप देखते हैं कि मैं संग्रहित प्रक्रियाओं से नफरत करता हूं जितना मुझे ट्रिगर पसंद है) क्या इसका मतलब है कि मुझे ट्रिगर छोड़ना है और कोड में घटाव भी करना है या किसी भी प्रकार ट्रिगर के अंदर अलग-अलग शुरू करने/निष्पादित होने के बावजूद ट्रांजैक्शन के अंदर होता है ... प्लेटफार्म/जगह (मेरी अंग्रेजी मुझे उम्मीद है कि मुझे पता है कि मेरा क्या मतलब है) – hretic

+0

मेरे पास एक और असंबंधित प्रश्न है, जैसा कि मैंने @lengyelg से पूछा: जिस तरह से मैं इसे देखता हूं कोड में प्रत्येक डालने के बाद डेटाबेस ट्रिगर में घटाना होता है, इसलिए एक ही टेबल में 2 प्रविष्टियां एक ही समय में नहीं हो सकती हैं (वास्तव में यह अनुमान लगा रहा हूं !! आप जानते हैं कि ऑटो वृद्धि आईडी आईडी के becuz को कुछ प्रकार का होना चाहिए सम्मिलन के लिए que भी मुझे लगता है कि वे एकल फिजिकल फ़ाइल में लिख रहे होंगे) 2 ट्रिगर्स एक ही समय में नहीं हो सकते हैं – hretic

+0

मैं एक और जवाब खत्म करने की कोशिश कर रहा हूं और मेरी माँ भोजन के साथ आती है और बब्बल है बकवास बकवास तो मैं बहुत अच्छी तरह से ध्यान केंद्रित नहीं कर सकता। थोड़ा सा आप में वापस आ जाएगा। – Drew

1

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

आपको अभी भी इस तरह से नहीं होना चाहिए, उदाहरण के लिए दौड़ की स्थिति को हटाया जाना चाहिए उदाहरण के लिए ताले (कुछ प्रदर्शन की लागत पर)।

+0

thanx, मुझे इसका नाम पता नहीं था ... जिस तरह से मैं इसे देखता हूं, कोड में प्रत्येक डालने के बाद डेटाबेस ट्रिगर में घटाना होता है, इसलिए एक ही टेबल में 2 प्रविष्टियां एक ही समय में नहीं हो सकती हैं (वास्तव में मैं इसे अनुमान लगा रहा हूं !! आप जानते हैं कि ऑटो वृद्धि आईडी के becuz को सम्मिलन के लिए कुछ प्रकार का क्यू होना चाहिए) 2 ट्रिगर्स एक ही समय में नहीं हो सकते – hretic

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

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