वेब एप्लिकेशन में दौड़ की स्थितियों को कैसे रोकें?


31

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

मेरे अनुभव में, वेब ऐप में ये मुद्दे बेहद सामान्य हैं। कुछ सॉफ़्टवेयर (उदाहरण के लिए विकी सॉफ़्टवेयर) के पास इसके विरुद्ध सुरक्षा है - आमतौर पर जब आप संपादन कर रहे थे तो "पेज को अपडेट किया गया था" के साथ दूसरा बचत विफल रहता है। लेकिन अधिकांश वेब साइटों में यह सुरक्षा नहीं होती है।

यह ध्यान देने योग्य है कि नियंत्रक विधियाँ स्वयं में थ्रेड-सुरक्षित हैं। आमतौर पर वे डेटाबेस लेनदेन का उपयोग करते हैं, जो उन्हें इस अर्थ में सुरक्षित बनाता है कि अगर ऐलिस और बॉब सटीक एक ही समय में बचाने की कोशिश करते हैं, तो यह भ्रष्टाचार का कारण नहीं होगा। दौड़ की स्थिति ऐलिस या बॉब के ब्राउज़र में बासी डेटा होने से उत्पन्न होती है।

हम इस तरह की दौड़ स्थितियों को कैसे रोक सकते हैं? विशेष रूप से, मैं जानना चाहूंगा:

  • क्या तकनीकों का उपयोग किया जा सकता है? उदाहरण के लिए अंतिम परिवर्तन के समय पर नज़र रखना। प्रत्येक का भला - बुरा क्या है।
  • एक सहायक उपयोगकर्ता अनुभव क्या है?
  • इस सुरक्षा को किस ढांचे में बनाया गया है?

आपने पहले ही जवाब दे दिया है: वस्तुओं के परिवर्तन की तारीख को ट्रैक करके और उस डेटा की आयु की तुलना करके जिसे अन्य परिवर्तन अपडेट करने का प्रयास करते हैं। क्या आप कुछ और जानना चाहते हैं, जैसे कि इसे कुशलता से कैसे किया जाए?
किलिआन फोथ

@KilianFoth - मैंने कुछ जानकारी जोड़ी है जो मैं विशेष रूप से जानना चाहता हूं
paj28

1
आपका प्रश्न वेब एप्लिकेशन के लिए किसी भी तरह से विशेष नहीं है, डेस्कटॉप एप्लिकेशन में बिल्कुल वही समस्या हो सकती है। विशिष्ट समाधान रणनीतियों का वर्णन यहां किया गया है: stackoverflow.com/questions/129329/…
Doc Brown

2
FYI करें, आपके प्रश्न में
उल्लिखित

Django से संबंधित कुछ चर्चा यहाँ
paj28

जवाबों:


17

आपको "अपने लेखन को पढ़ने" की आवश्यकता है, जिसका अर्थ है कि परिवर्तन लिखने से पहले, आपको रिकॉर्ड को फिर से पढ़ने और यह जांचने की आवश्यकता है कि आपके द्वारा पिछली बार इसे पढ़ने के बाद इसमें कोई बदलाव कहां हुआ है। आप इस फील्ड-बाय-फील्ड (बारीक-दाने वाले) या टाइमस्टैम्प (मोटे अनाज वाले) के आधार पर कर सकते हैं। जब आप यह जांच करते हैं तो आपको रिकॉर्ड पर एक विशेष लॉक की आवश्यकता होती है। यदि कोई परिवर्तन नहीं किए गए थे, तो आप अपने परिवर्तनों को लिख सकते हैं और लॉक जारी कर सकते हैं। यदि इस बीच रिकॉर्ड बदल गया है, तो आप लेन-देन को निरस्त करते हैं, लॉक जारी करते हैं और उपयोगकर्ता को सूचित करते हैं।


यह सबसे व्यावहारिक दृष्टिकोण की तरह लगता है। क्या आप इसे लागू करने वाले किसी ढांचे के बारे में जानते हैं? मुझे लगता है कि इस योजना के साथ सबसे बड़ी समस्या यह है कि एक सरल "एडिट संघर्ष" संदेश उपयोगकर्ताओं को निराश करेगा, लेकिन परिवर्तनों (मैन्युअल रूप से या स्वचालित रूप से) को मर्ज करने का प्रयास मुश्किल है।
15:28 पर पज

दुर्भाग्य से, मैं किसी भी ऐसे ढांचे को नहीं जानता जो इस बॉक्स से बाहर का समर्थन करता है। मुझे नहीं लगता कि एडिट कॉन्फ्लिक्ट एरर मैसेज को निराशा के रूप में माना जाएगा, जब तक कि यह अक्सर ऊपर नहीं आता है। अंततः, यह सिस्टम के उपयोगकर्ता भार पर निर्भर करता है कि आप केवल टाइमस्टैम्प की जाँच करें या अधिक जटिल विलय कार्य को लागू करें।
फिल

मैंने एक पीसी वितरित डेटाबेस उत्पाद को बनाए रखा जो ठीक-ठाक दृष्टिकोण (इसके स्थानीय डेटाबेस कॉपी के खिलाफ) का उपयोग करता था: यदि एक उपयोगकर्ता ने कीमत बदल दी और दूसरे ने विवरण बदल दिया - कोई समस्या नहीं! जैसा कि वास्तविक जीवन में होता है। यदि दो उपयोगकर्ताओं ने कीमत बदल दी है - 2 वें उपयोगकर्ता को माफी मिल जाती है और फिर से अपने बदलाव की कोशिश करता है। कोई बात नहीं! यह उस समय के दौरान ताले को छोड़कर आवश्यकता नहीं है जब डेटा डेटाबेस को लिखा जा रहा हो। इससे कोई फर्क नहीं पड़ता कि एक उपयोगकर्ता दोपहर के भोजन पर जाता है जबकि स्क्रीन पर उनका परिवर्तन होता है और इसे बाद में सबमिट करता है। दूरस्थ डेटाबेस परिवर्तनों के लिए, यह रिकॉर्ड टाइमस्टैम्प पर आधारित था।

1
डेटफ्लेक्स में एक फ़ंक्शन था जिसे "रेरड ()" कहा जाता है, जो कि आप का वर्णन करता है। बाद के संस्करणों में, यह एक बहुपक्षीय वातावरण में सुरक्षित था। और, वास्तव में, यह काम करने के लिए इस तरह के interleaved अद्यतन प्राप्त करने का एकमात्र तरीका था।

क्या आप sql सर्वर के साथ ऐसा करने का एक उदाहरण दे सकते हैं? \
l --''''''--------- '' '' '' '' '' '23

10

मैंने 2 मुख्य तरीके देखे हैं:

  1. पृष्ठ के अंतिम अद्यतन का टाइमस्टैम्प जोड़ें जिसका उपयोग एक छिपे हुए इनपुट में संपादन कर रहा है। जब टाइमस्टैम्प को चालू करने के खिलाफ जाँच की जाती है और यदि वे मेल नहीं खाते हैं तो इसे किसी और ने अपडेट किया है और एक त्रुटि लौटाता है।

    • प्रो: कई उपयोगकर्ता पृष्ठ के विभिन्न हिस्सों को संपादित कर सकते हैं। त्रुटि पृष्ठ एक भिन्न पृष्ठ पर ले जा सकता है जहां दूसरा उपयोगकर्ता नए पृष्ठ में अपने परिवर्तनों को मर्ज कर सकता है।

    • con: कुछ समय में बड़े समवर्ती संपादन के दौरान प्रयास के बड़े हिस्से बर्बाद हो जाते हैं।

  2. जब कोई उपयोगकर्ता पृष्ठ को समय की उचित मात्रा के लिए संपादित करना शुरू करता है, जब कोई अन्य उपयोगकर्ता तब संपादित करने का प्रयास करता है तो उसे एक त्रुटि पृष्ठ मिलता है और तब तक इंतजार करना पड़ता है जब तक कि ताला समाप्त नहीं हो जाता है या पहला उपयोगकर्ता प्रतिबद्ध नहीं होता है।

    • समर्थक: संपादित प्रयास व्यर्थ नहीं हैं।

    • con: एक भद्दा उपयोगकर्ता किसी पृष्ठ को अनिश्चित काल के लिए बंद कर सकता है। एक समय समाप्त ताला के साथ एक पृष्ठ अभी भी करने में सक्षम हो सकता है जब तक अन्यथा के साथ निपटा नहीं (तकनीक 1 का उपयोग करके)


7

ऑप्टिमिस्टिक कंसीलर कंट्रोल का उपयोग करें ।

एक वर्जननंबर या वर्जनटेमस्टैम्प कॉलम को तालिका में प्रश्न में जोड़ें (पूर्णांक सबसे सुरक्षित है)।

उपयोगकर्ता 1 रिकॉर्ड पढ़ता है:

{id:1, status:unimportant, version:5}

उपयोगकर्ता 2 रिकॉर्ड पढ़ता है:

{id:1, status:unimportant, version:5}

उपयोगकर्ता 1 रिकॉर्ड बचाता है, यह संस्करण बढ़ाता है:

save {id:1, status:important, version:5}
new value {id:1, status:important, version:6}

उपयोगकर्ता 2 उनके द्वारा पढ़े गए रिकॉर्ड को बचाने की कोशिश करता है:

save {id:1, status:unimportant, version:5}
ERROR

हाइबरनेट / जेपीए @Versionएनोटेशन के साथ स्वचालित रूप से कर सकते हैं

आपको आम तौर पर सत्र में रीड रिकॉर्ड की स्थिति बनाए रखने की आवश्यकता होती है (यह एक छिपे हुए रूप में चर की तुलना में सुरक्षित है)।


धन्यवाद ... विशेष रूप से @Version के बारे में जानने में मददगार। एक सवाल: सत्र में राज्य को संग्रहीत करना क्यों सुरक्षित है? उस स्थिति में मुझे चिंता होगी कि बैक बटन का उपयोग करने से चीजें भ्रमित हो सकती हैं।
पज

सत्र एक छिपे हुए रूप तत्व से अधिक सुरक्षित है क्योंकि उपयोगकर्ता संस्करण मान को बदलने में सक्षम नहीं होगा। यदि यह चिंता का विषय नहीं है, तो सत्र के बारे में भाग को नजरअंदाज करें
नील मैकगिन

इस तकनीक को आशावादी ऑफ़लाइन लॉक कहा जाता है और यह SQLAlchemy में भी है
paj28

@ paj28 - SQLAlchemyआशावादी ऑफ़लाइन ताले के बारे में कुछ भी इंगित करने के लिए यह लिंक नहीं है, और मैं इसे डॉक्स में नहीं पा सकता हूं। क्या आपके पास अधिक सहायक लिंक था, या केवल SQLAlchemy पर लोगों को सामान्य रूप से इंगित कर रहा था?
dwanderson

@dwanderson I का मतलब उस लिंक के वर्जन काउंटर पार्ट से था।
पज

1

कुछ ऑब्जेक्ट रिलेशनल मैपिंग (ओआरएम) सिस्टम यह पता लगाएंगे कि डेटाबेस से लोड किए जाने के बाद से ऑब्जेक्ट के कौन से क्षेत्र बदल गए हैं, और केवल उन मूल्यों को सेट करने के लिए SQL अपडेट स्टेटमेंट का निर्माण करेगा। रूबी के लिए ActiveRecord रेल पर एक ऐसा ORM है।

शुद्ध प्रभाव यह है कि उपयोगकर्ता द्वारा बदले गए फ़ील्ड को डेटाबेस में भेजे गए UPDATE कमांड में शामिल नहीं किया गया है। जो लोग एक ही समय में विभिन्न क्षेत्रों को अपडेट करते हैं, वे एक-दूसरे के बदलावों को अधिलेखित नहीं करते हैं।

आप किस प्रोग्रामिंग भाषा का उपयोग कर रहे हैं, इस पर निर्भर करता है कि कौन से ओआरएम उपलब्ध हैं, अनुसंधान करें और देखें कि क्या उनमें से कोई भी आपके एप्लिकेशन में "गंदे" चिह्नित डेटाबेस में केवल कॉलम अपडेट करेगा।


हाय ग्रेग दुर्भाग्य से, यह इन प्रकार की दौड़ स्थितियों के साथ मदद नहीं करता है। यदि आप मेरे मूल उदाहरण पर विचार करते हैं, जब ऐलिस बचाता है, तो ओआरएम मूल्य स्तंभ को गंदे के रूप में देखेगा और इसे अपडेट करेगा - भले ही अपडेट वांछित न हो।
पज

1
@ paj28 ग्रेग के जवाब में मुख्य बिंदु " फ़ील्ड उपयोगकर्ता को नहीं बदला "। ऐलिस ने कीमत नहीं बदली, इसलिए ORM डेटाबेस में "मूल्य" मूल्य को बचाने की कोशिश नहीं करेगा।
रॉस पैटरसन

@RossPatterson - ORM उपयोगकर्ता द्वारा ब्राउज़र से बदले गए फ़ील्ड और डेटा को बासी करने के बीच के अंतर को कैसे जानता है? यह कम से कम कुछ अतिरिक्त ट्रैकिंग किए बिना नहीं करता है। यदि आप ऐसे ट्रैकिंग को शामिल करने के लिए ग्रेग के उत्तर को संपादित करना चाहते हैं, या कोई अन्य उत्तर प्रस्तुत करना चाहते हैं, तो यह उपयोगी होगा।
पज

@ paj28 सिस्टम के कुछ भाग को यह जानना होता है कि उपयोगकर्ता ने क्या किया और उपयोगकर्ता द्वारा किए गए परिवर्तनों को केवल संग्रहीत करता है। यदि उपयोगकर्ता ने कीमत बदल दी है, तो उसे वापस बदल दिया, फिर सबमिट किया गया, इसे "उपयोगकर्ता द्वारा बदले गए कुछ" के रूप में नहीं गिना जाना चाहिए, क्योंकि उन्होंने ऐसा नहीं किया। यदि आपके पास एक ऐसी प्रणाली है जिसके लिए इस स्तर के संगरोध नियंत्रण की आवश्यकता है, तो आपको इसे इस तरह से बनाना होगा। यदि नहीं, तो नहीं।

@nocomprende - कुछ हिस्सा, निश्चित - लेकिन नहीं ORM इस जवाब के रूप में कहते हैं
paj28
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.