2011-08-28 12 views
5

यहां दो संभावित वर्कफ़्लो हैं जिन्हें मैं वेब एप्लिकेशन में करना चाहता हूं।मैं वेब एप्लिकेशन में समवर्ती परिवर्तनों से कैसे निपटूं?

रूपांतर 1

  • उपयोगकर्ता अनुरोध भेजता है
  • सर्वर पढ़ता डेटा
  • सर्वर डेटा
  • सर्वर डेटा

विविधता 2 संशोधित बचाता को संशोधित करता है:

  • उपयोगकर्ता भेजता का अनुरोध
  • सर्वर पढ़ता डेटा
  • सर्वर उपयोगकर्ता के लिए डेटा भेजता है
  • उपयोगकर्ता संशोधनों के साथ अनुरोध भेजता है
  • सर्वर संशोधित डेटा

इन मामलों में से प्रत्येक में बचत होती है, मैं सोच रहा हूँ: यह सुनिश्चित करने के लिए मानक दृष्टिकोण क्या हैं कि इस सेवा के समवर्ती उपयोग सेन परिणाम मिलेगा? (यानी कोई भी नहीं की संपादित clobbered हो जाता है, मानों कुछ संपादन आदेश के लिए, आदि अनुरूप)

स्थिति काल्पनिक है, लेकिन यहाँ है जहाँ मैं व्यवहार में इस समस्या से निपटने की जरूरत है की संभावना है उनके कुछ विवरण हैं:

  • वेब अनुप्रयोग, लेकिन
  • संभावित अनिर्दिष्ट भाषा, एक वेब ढांचे का उपयोग कर
  • डेटा संग्रह एक एसक्यूएल रिलेशनल डेटाबेस है
  • तर्क शामिल एक प्रश्न जैसे में अच्छी तरह से व्यक्त करने के लिए बहुत जटिल है मूल्य = मान + 1

मुझे लगता है कि मैं यहां पहिया को आजमाने और पुन: पेश करने की इच्छा नहीं करना चाहूंगा। निश्चित रूप से ये ज्ञात समाधानों के साथ अच्छी तरह से ज्ञात समस्याएं हैं। कृपया सलाह दें।

धन्यवाद।

उत्तर

4

मेरे सर्वोत्तम ज्ञान के लिए, समस्या का कोई सामान्य समाधान नहीं है।

समस्या की जड़ यह है कि उपयोगकर्ता डेटा पुनर्प्राप्त कर सकता है और अद्यतन और बचत करने से पहले लंबे समय तक स्क्रीन पर इसे देख सकता है।

मैं तीन बुनियादी दृष्टिकोण के बारे में पता:

  1. उपयोगकर्ता डेटाबेस को पहचान लेगा, रिकॉर्ड ताला, और जब तक उपयोगकर्ता अपडेट बचाता जारी नहीं करते। अभ्यास में, यह जंगली अव्यवहारिक है। क्या होगा यदि उपयोगकर्ता एक स्क्रीन लाता है और फिर बिना बचत के दोपहर के भोजन के लिए जाता है? या दिन के लिए घर जाता है? या इतनी निराश है कि इस बेवकूफ रिकॉर्ड को अपडेट करने की कोशिश कर रहा है कि वह छोड़ देता है और कभी वापस नहीं आता है?

  2. अपने अपडेट को गंतव्यों के बजाय डेल्टा के रूप में व्यक्त करें। क्लासिक उदाहरण लेने के लिए, मान लें कि आपके पास एक ऐसी प्रणाली है जो सूची में स्टॉक रिकॉर्ड करती है। हर बार बिक्री होती है, आपको सूची गणना से 1 (या अधिक) घटा देना चाहिए।

तो कहें कि वर्तमान मात्रा हाथ पर है 10. उपयोगकर्ता ए बिक्री करता है। वर्तमान मात्रा = 10. उपयोगकर्ता बी बिक्री बनाता है। उन्हें वर्तमान मात्रा = 10. भी मिलती है। उपयोगकर्ता ए प्रवेश करता है कि दो इकाइयां बेची जाती हैं। नई मात्रा = 10 - 2 = 8. सहेजें। उपयोगकर्ता बी बेची गई एक यूनिट में प्रवेश करती है। नई मात्रा = 10 (वह मूल्य जो भारित है) - 1 = 9. सहेजें। जाहिर है, कुछ गलत हो गया।

समाधान: "इन्वेंट्री सेट मात्रा = 9 जहां आइटम आईडी = 12345" लिखने के बजाय, "इन्वेंट्री सेट मात्रा = मात्रा -1 अपडेट करें जहां itemid = 12345" लिखने के बजाय लिखें। फिर डेटाबेस को अद्यतन कतार दें। यह रणनीति # 1 से बहुत अलग है, क्योंकि डेटाबेस को केवल इसे पढ़ने के लिए रिकॉर्ड को लॉक करना होगा, अपडेट करना होगा, और इसे लिखना होगा। जब कोई स्क्रीन पर नजर रखता है तो उसे इंतजार नहीं करना पड़ता है।

बेशक, यह केवल उन परिवर्तनों के लिए उपयोग योग्य है जिन्हें डेल्टा के रूप में व्यक्त किया जा सकता है। यदि आप कहते हैं, ग्राहक के फोन नंबर को अपडेट कर रहे हैं, तो यह काम नहीं करेगा। (जैसे, पुराना नंबर 555-1234 है। उपयोगकर्ता ए इसे 555-1235 में बदलने के लिए कहता है। यह +1 का परिवर्तन है। उपयोगकर्ता बी इसे 555-1243 में बदलने के लिए कहता है। यह +9 का परिवर्तन है। इसलिए कुल परिवर्तन है +10, ग्राहक का नया नंबर 555-1244 है। :-)) लेकिन ऐसे मामलों में, "अंतिम उपयोगकर्ता प्रवेश कुंजी जीतने के लिए अंतिम उपयोगकर्ता" शायद सबसे अच्छा है जो आप वैसे भी कर सकते हैं।

  1. अद्यतन पर, जांचें कि डेटाबेस में प्रासंगिक फ़ील्ड आपके "से" मूल्य से मेल खाते हैं। उदाहरण के लिए, कहें कि आप अपने ग्राहकों के लिए अनुबंधों पर बातचीत करने वाली एक कानूनी फर्म के लिए काम करते हैं। आपके पास एक स्क्रीन है जहां उपयोगकर्ता बातचीत के बारे में नोट्स दर्ज कर सकता है। उपयोगकर्ता ए अनुबंध अनुबंध लाता है। उपयोगकर्ता बी एक ही अनुबंध रिकॉर्ड लाता है। उपयोगकर्ता ए प्रवेश करता है कि उसने फोन पर दूसरी पार्टी से बात की और वे प्रस्तावित शर्तों के लिए सहमत हैं। यूजर बी, जो दूसरी पार्टी को फोन करने की भी कोशिश कर रहा है, प्रवेश करता है कि वे फोन कॉल का जवाब नहीं दे रहे हैं और उन्हें संदेह है कि वे पत्थर मार रहे हैं। उपयोगकर्ता ए क्लिक बचाता है। क्या हम उपयोगकर्ता बी की टिप्पणियों को उपयोगकर्ता ए को ओवरराइट करना चाहते हैं? शायद ऩही। इसके बजाए हम एक संदेश दिखाते हैं कि रिकॉर्ड पढ़ने के बाद से नोट्स बदल दिए गए हैं, और यह तय करने से पहले कि वह सहेजने, निरस्त करने या कुछ अलग करने के साथ आगे बढ़ने के लिए आगे बढ़ने से पहले नया मान देखने की इजाजत दे।

[नोट: फ़ोरम स्वचालित रूप से मेरी क्रमांकित सूचियों को पुनर्निर्मित कर रहा है। मुझे यकीन नहीं है कि इसे कैसे ओवरराइड करें।]

0

आवेदन परत में चीजें सरल हैं - प्रत्येक अनुरोध को एक अलग थ्रेड (या प्रक्रिया) द्वारा परोसा जाता है, इसलिए जब तक कि आपके प्रसंस्करण कक्षाओं (सेवाओं) में राज्य न हो, सब कुछ सुरक्षित है।

जब आप डेटाबेस तक पहुंचते हैं तो चीजें अधिक जटिल होती हैं - यानी जहां राज्य आयोजित होता है। यह सुनिश्चित करने के लिए कि सब कुछ ठीक है, आपको transactions की आवश्यकता है।

लेनदेन में गुणों का एक सेट है - ACID, "गारंटी डेटाबेस लेनदेन विश्वसनीय रूप से संसाधित होते हैं"।

+0

धन्यवाद। यह बदलाव 1 के लिए ठीक काम करता है। लेकिन, इस स्थिति से निपटने का सामान्य तरीका क्या है जहां आपके पास लेनदेन नहीं है? जैसेMySQL का MyISAM – Ming

+0

स्पष्टीकरण के लिए, मुझे कल्पना है कि बहुत सारे फ़ोरम सॉफ़्टवेयर को इस तरह के मुद्दे से निपटना होगा। फिर भी, मुझे लगता है कि उनमें से कई माईसाम का उपयोग करते हैं, जिनमें लेनदेन नहीं होते हैं। इसका उनका संकल्प क्या है? – Ming

+0

आप विश्वसनीय रूप से इसके साथ सौदा नहीं कर सकते हैं। फ़ोरम सॉफ़्टवेयर मुख्य रूप से आवेषण पर निर्भर करता है, और शायद ही कभी समवर्ती संपादन पर निर्भर करता है, इसलिए यह कई समस्याओं का कारण नहीं बनता है – Bozho

0

यदि आपके पास MySQL में लेन-देन नहीं हैं, तो आप यह सुनिश्चित करने के लिए अद्यतन कमांड का उपयोग कर सकते हैं कि डेटा दूषित नहीं है।

UPDATE tableA SET status=2 WHERE status = 1 

यदि स्थिति एक है, तो केवल एक प्रक्रिया को परिणाम प्राप्त होता है कि एक रिकॉर्ड अपडेट किया गया था। नीचे दिए गए कोड में, रिटर्न -1 अगर अपडेट निष्पादित नहीं किया गया था (यदि अपडेट करने के लिए कोई पंक्ति नहीं थी)।

PreparedStatement query; 
query = connection.prepareStatement(s); 
int rows = -1; 
try 
{ 
    rows = query.executeUpdate(); 
    query.close(); 
} 
catch (Exception e) 
{ 
    e.printStackTrace(); 
} 
return rows; 
संबंधित मुद्दे