नॉन-रिपीटेबल रीड और फैंटम रीड में क्या अंतर है?


154

नॉन रिपीटेबल रीड और फैंटम रीड के बीच क्या अंतर है?

मैंने विकिपीडिया से अलगाव (डेटाबेस सिस्टम) लेख पढ़ा है , लेकिन मुझे कुछ संदेह है। नीचे दिए गए उदाहरण में, क्या होगा: गैर-दोहराने योग्य पढ़ा और प्रेत पढ़ा ?

लेन-देन ए
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
उत्पादन:
1----MIKE------29019892---------5000
लेन-देन B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
लेन-देन ए
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

एक और संदेह है, उपरोक्त उदाहरण में, किस अलगाव स्तर का उपयोग किया जाना चाहिए? और क्यों?


जवाबों:


165

विकिपीडिया से (जिसके पास इसके लिए महान और विस्तृत उदाहरण हैं):

एक गैर-दोहराने योग्य रीड तब ​​होता है, जब एक लेनदेन के दौरान, एक पंक्ति को दो बार पुनर्प्राप्त किया जाता है और पंक्ति के भीतर के मान को रीड्स के बीच भिन्न होता है।

तथा

एक प्रेत रीड तब ​​होता है, जब एक लेन-देन के दौरान, दो समान प्रश्नों को निष्पादित किया जाता है, और दूसरी क्वेरी द्वारा लौटी पंक्तियों का संग्रह पहले से अलग होता है।

सरल उदाहरण:

  • उपयोगकर्ता A एक ही क्वेरी को दो बार चलाता है।
  • बीच में, उपयोगकर्ता बी एक लेनदेन चलाता है और करता है।
  • गैर-दोहराए जाने वाला पढ़ा: उपयोगकर्ता A ने एक पंक्ति को दूसरी बार अलग मान दिया है।
  • प्रेत पढ़ा: क्वेरी में सभी पंक्तियों का मूल्य पहले और बाद में समान है, लेकिन विभिन्न पंक्तियों का चयन किया जा रहा है (क्योंकि B ने कुछ को हटा दिया है या डाला है)। उदाहरण: select sum(x) from table;यदि कोई प्रभावित पंक्तियाँ स्वयं अपडेट नहीं की गई हैं, यदि पंक्तियों को जोड़ा या हटा दिया गया है, तो भी एक अलग परिणाम देगा।

उपरोक्त उदाहरण में, किस अलगाव स्तर का उपयोग किया जाना है?

आपको किस अलगाव स्तर की आवश्यकता है यह आपके आवेदन पर निर्भर करता है। एक "बेहतर" अलगाव स्तर (जैसे कम संगामना) के लिए एक उच्च लागत है।

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


6
मैं वास्तव में इस तरह के वाक्यविन्यास के तर्क को नहीं समझता ... एक गैर-दोहराने योग्य रीड तब ​​होता है जब रीड दोहराया जाता है (और प्राप्त एक अलग मूल्य) ??! ...
serhio

14
@serhio "गैर-दोहराने योग्य" इस तथ्य को संदर्भित करता है कि आप एक बार मूल्य पढ़ सकते हैं और परिणाम के रूप में x प्राप्त कर सकते हैं, और फिर फिर से पढ़ सकते हैं और परिणाम के रूप में y प्राप्त कर सकते हैं, इसलिए आप दो से एक ही परिणाम दोहरा नहीं सकते हैं (गैर-दोहराने योग्य) एक ही पंक्ति के अलग-अलग क्वेरी, क्योंकि उस पंक्ति मान को रीड के बीच में अपडेट किया गया था।
1

@ थाइलो किसी भी वास्तविक उपयोग के मामले का उदाहरण जहां रिपीटेबल-रीड संभव मुद्दों को बना सकता है और जहां यह आवश्यक है?
user104309

क्या होगा यदि पीके को किसी अन्य लेनदेन में संशोधित किया जाए? क्या उस परिणाम को एक प्रेत पढ़ सकता है? (ज्यादातर मामलों में एक अजीब बात है, लेकिन असंभव नहीं है।)
jpmc26

1
दोनों मुझे एक ही लगते हैं
sn.anurag

125

एक आसान तरीका है जिसके बारे में मुझे सोचना है:

गैर-दोहराने योग्य और प्रेत रीड दोनों को एक अलग लेनदेन से डेटा संशोधन संचालन के साथ करना पड़ता है, जो आपके लेनदेन के शुरू होने के बाद प्रतिबद्ध थे, और फिर आपके लेनदेन द्वारा पढ़े गए थे।

गैर-दोहराए जाने वाले रीड तब ​​होते हैं जब आपका लेनदेन किसी अन्य लेनदेन से प्रतिबद्ध अद्यतन पढ़ता है । जब आपकी लेन-देन शुरू हुई थी तो उसी पंक्ति में अब अलग-अलग मूल्य हैं।

समान हैं, लेकिन जब प्रतिबद्ध से पढ़ने प्रेत पढ़ता आवेषण और / या हटाता है एक और लेन-देन से। आपके द्वारा लेन-देन शुरू करने के बाद से नई पंक्तियाँ या पंक्तियाँ गायब हो गई हैं।

डर्टी रीड गैर-दोहराने योग्य और प्रेत रीड के समान होते हैं , लेकिन UNCOMMITTED डेटा पढ़ने से संबंधित होते हैं, और तब होते हैं जब एक अन्य लेनदेन से एक अद्यतन, इन्सर्ट या DELETE पढ़ा जाता है, और दूसरा लेनदेन अभी तक डेटा के लिए प्रतिबद्ध नहीं है। यह "प्रगति पर" डेटा पढ़ रहा है, जो पूर्ण नहीं हो सकता है, और वास्तव में कभी भी प्रतिबद्ध नहीं हो सकता है।


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

1
@PHPAvenger यहां READ UNCOMMITTED आइसोलेशन स्तर के लिए एक उपयोग मामला है: एक चयन और अपडेट क्वेरी ( यहां समझाया गया है ) के बीच एक गतिरोध का सामना करने की संभावना हमेशा होती है । यदि कवरिंग इंडेक्स बनाने के लिए चयन क्वेरी बहुत जटिल है, तो डेडलॉक से बचने के लिए आप गंदे रीड्स से मुठभेड़ के जोखिम के साथ READ UNCOMMITED अलगाव स्तर का उपयोग करना चाहते हैं, लेकिन कितनी बार आप गंदे रीड्स के बारे में चिंता करने के लिए रोलबैक लेनदेन नहीं करते हैं। स्थायी होना ?!
पेट्रीकामार्टिनस्क्यू

1
@ petrica.martinescu गंदे रीड्स के कारण होने वाली समस्याओं के बारे में अभी नहीं है कि क्या लेनदेन वापस ले लिया गया है या नहीं। लंबित लेनदेन में डेटा को कैसे संशोधित किया गया है, इसके आधार पर गंदे रीडर्स बहुत गलत परिणाम दे सकते हैं। एक लेनदेन की कल्पना करें जो कई हटाए गए, अपडेट और / या आवेषण की एक श्रृंखला करता है। यदि आप "पढ़े बिना पढ़े" का उपयोग करके उस लेनदेन के बीच में डेटा पढ़ते हैं, तो यह अधूरा है। स्नैपशॉट आइसोलेशन स्तर (SQL सर्वर में) बिना पढ़े पढ़ने के लिए एक बेहतर विकल्प है। एक उत्पादन प्रणाली में बिना पढ़े हुए आइसोलेशन स्तर के लिए मान्य उपयोग का मामला दुर्लभ IMO है।
13

2
@DiponRoy महान सवाल। यदि दोहराने योग्य पठनीय (आरआर) अलगाव का उपयोग करते हुए लॉकिंग को हटा दिया गया है, तो उन पंक्तियों को हटाने से रोका जाना चाहिए जिन्हें चुना गया है। मैंने पिछले कुछ वर्षों में 2 आईएसओ स्तर की अलग-अलग परिभाषाएँ देखी हैं, मुख्य रूप से कहा जाता है कि संग्रह में एक परिवर्तन है / # पंक्तियाँ वापस आ गई हैं और आरआर उसी पंक्ति को बदला जा रहा है। मैंने अभी-अभी अपडेट किए गए MS SQL डॉक्युमेंट की जाँच की है कि डिलीट न करने वाले आरआर का कारण बन सकते हैं ( docs.microsoft.com/en-us/sql/odbc/reference/develop-app/… ) इसलिए मुझे लगता है कि ग्रुप डिलीट करना सुरक्षित होगा RR श्रेणी भी
BateTech

2
@anir हाँ सम्मिलित करता है और हटाता है गंदे रीड्स में शामिल हैं। उदाहरण: लेन-देन शुरू करें, कनेक्शन पर 100 चालान लाइनों में से 2 डालें a, अब कनेक्शन b उन 2 पंक्तियों को पढ़ता है जिससे पहले trx प्रतिबद्ध है और अन्य 98 लाइनों को जोड़ने से पहले, और इसलिए चालान के लिए सभी जानकारी शामिल नहीं करता है। यह एक गंदा पाठ सम्मिलित होगा।
बीटेकटेक

28

जैसा कि इस लेख में बताया गया है , गैर-दोहराने योग्य पढ़ें विसंगति इस प्रकार है:

यहाँ छवि विवरण दर्ज करें

  1. ऐलिस और बॉब दो डेटाबेस लेनदेन शुरू करते हैं।
  2. बॉब के पोस्ट रिकॉर्ड और शीर्षक कॉलम का मूल्य लेन-देन है।
  3. ऐलिस ACID के मान को दिए गए पोस्ट रिकॉर्ड के शीर्षक को संशोधित करता है।
  4. ऐलिस उसके डेटाबेस लेनदेन करता है।
  5. यदि बॉब पोस्ट रिकॉर्ड को फिर से पढ़ता है, तो वह इस तालिका पंक्ति का एक अलग संस्करण देखेगा।

प्रेत पढ़ने के बारे में इस लेख में , आप देख सकते हैं कि यह विसंगति इस प्रकार हो सकती है:

यहाँ छवि विवरण दर्ज करें

  1. ऐलिस और बॉब दो डेटाबेस लेनदेन शुरू करते हैं।
  2. बॉब 1 के पहचानकर्ता मान के साथ पोस्ट पंक्ति के साथ जुड़े सभी पोस्ट_कम रिकॉर्ड को पढ़ता है।
  3. ऐलिस एक नया पोस्ट_कॉममेंट रिकॉर्ड जोड़ता है जो पोस्ट पंक्ति के साथ जुड़ा हुआ है जिसमें पहचानकर्ता मान 1 है।
  4. ऐलिस उसके डेटाबेस लेनदेन करता है।
  5. यदि बॉब पुन: पढ़ता है post_comment रिकॉर्ड 1 के बराबर post_id कॉलम मान रखता है, तो वह इस परिणाम सेट के एक भिन्न संस्करण का अवलोकन करेगा।

इसलिए, जबकि गैर-दोहराने योग्य रीड एक पंक्ति में लागू होता है, प्रेत रीड रिकॉर्ड की एक श्रेणी के बारे में है जो किसी दिए गए क्वेरी फ़िल्टरिंग मानदंड को पूरा करता है।


3
शानदार दृश्य @Vlad
dextermini

23

घटनाएं पढ़ें

  • गंदा पढ़ता है : दूसरे लेनदेन से UNCOMMITED डेटा पढ़ें
  • गैर-दोहराने योग्य रीड :UPDATEकिसी अन्य ट्रांज़ेक्शन के क्वेरी सेकमिटेड डेटा पढ़ें
  • प्रेत पढ़ता है :किसी अन्य लेन-देन से एक क्वेरीINSERTयासंचारित डेटा पढ़ेंDELETE

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

हम यह भी देख सकते हैं कि वास्तविक इनसेट या DELETES के बजाय ज्यादातर उपयोग के मामलों में UPDATES अधिक लगातार काम हो सकता है (ऐसे मामलों में, गैर-दोहराने योग्य रीड का खतरा केवल बना रहता है - उन मामलों में प्रेत रीड संभव नहीं हैं)। यही कारण है कि UPDATES को INSERT-DELETE से अलग तरीके से व्यवहार किया जाता है और परिणामस्वरूप विसंगति को भी अलग नाम दिया जाता है।

यूपीडेट्स को संभालने के बजाय INSERT-DELETEs से निपटने के लिए एक अतिरिक्त प्रसंस्करण लागत भी है।


विभिन्न अलगाव स्तरों के लाभ

  • READ_UNCOMMITTED कुछ नहीं रोकता है। यह शून्य अलगाव स्तर है
  • READ_COMMITTED सिर्फ एक को रोकता है, यानी डर्टी रीड
  • REPEATABLE_READ दो विसंगतियों को रोकता है: गंदा पढ़ता है और गैर-दोहराने योग्य पढ़ता है
  • अनुक्रमिक तीनों विसंगतियों को रोकता है: डर्टी रीड्स, नॉन-रिपीटेबल रीड्स और फैंटम रीड्स

तो फिर हर समय केवल लेनदेन को ही क्यों न करें? ठीक है, उपरोक्त प्रश्न का उत्तर है: अनुक्रमिक सेटिंग लेनदेन को बहुत धीमा कर देती है , जिसे हम फिर से नहीं चाहते हैं।

वास्तव में लेन-देन के समय की खपत निम्न दर में है:

अनुक्रमिक > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED

तो READ_UNCOMMITTED सेटिंग सबसे तेज़ है


सारांश

वास्तव में हमें उपयोग के मामले का विश्लेषण करने और एक अलगाव स्तर तय करने की आवश्यकता है ताकि हम लेनदेन के समय का अनुकूलन कर सकें और अधिकांश विसंगतियों को भी रोक सकें।

ध्यान दें कि डिफ़ॉल्ट रूप से डेटाबेस में REPEATABLE_READ सेटिंग है।


1
UPDATE या DELETE दोनों गैर-दोहराने योग्य रीड के लिए जगह ले सकते हैं या यह केवल UPDATE है?
दीपोन रॉय

1
गैर-पढ़े जाने के लिए UPDATE या DELETE दोनों हो सकते हैं
niket patel

वास्तव में हम संक्षेप में बता सकते हैं कि एक ही डेटाबेस पर एक अन्य लेनदेन द्वारा निष्पादित एक यादृच्छिक DELETE विवरण में वर्तमान लेनदेन के लिए गैर-दोहराने योग्य रीड के कारण होने की बहुत कम संभावना है। लेकिन उसी डिलीट स्टेटमेंट में मौजूदा ट्रांजेक्शन के लिए फैंटम पढ़ने का 100% मौका है। इसे इस तरह से देखते हुए, यदि आप इसे शब्द के लिए लेते हैं, तो मेरा लेखन थोड़ा गलत है। लेकिन हे, मैंने जानबूझकर इसे इस तरह से लिखा है ताकि पाठक को और अधिक स्पष्ट हो सके।
सुभदीप रे

एक सरल और समझने में आसान के लिए +1। हालाँकि मुझे लगता है कि अधिकांश डेटाबेस (oracle, mysql) में एक अलग-थलग आइसोलेशन लेवल ऑफ़ रीड
कमिटेड है

7

इन दो प्रकार के अलगाव स्तरों के बीच कार्यान्वयन में अंतर है।
"गैर-दोहराने योग्य पढ़ने" के लिए, पंक्ति-लॉकिंग की आवश्यकता होती है।
"फैंटम रीड" के लिए ed स्कोप-लॉकिंग की आवश्यकता है, यहां तक ​​कि टेबल-लॉकिंग भी।
हम दो-चरण-लॉकिंग प्रोटोकॉल का उपयोग करके इन दो स्तरों को लागू कर सकते हैं ।


बार-बार पढ़ने योग्य या अनुक्रमिक लागू करने के लिए, पंक्ति-लॉकिंग का उपयोग करने की आवश्यकता नहीं है।
a_horse_with_no_name 20

5

गैर-दोहराने योग्य रीड्स के साथ एक प्रणाली में, लेन-देन ए की दूसरी क्वेरी का परिणाम लेनदेन बी में अपडेट को प्रतिबिंबित करेगा - यह नई राशि को देखेगा।

ऐसी प्रणाली में, जो प्रेत रीड की अनुमति देती है, यदि Transaction B को ID = 1 के साथ एक नई पंक्ति सम्मिलित करनी थी, तो दूसरी क्वेरी के निष्पादित होने पर Transaction A नई पंक्ति को देखेगा; यानी फैंटम रीड्स गैर-दोहराने योग्य रीड का एक विशेष मामला है।


मुझे नहीं लगता कि एक प्रेत की व्याख्या सही है। नॉन-कमिट डेटा न दिखने पर भी आप फैंटम रीड प्राप्त कर सकते हैं। विकिपीडिया पर उदाहरण देखें (ऊपर टिप्पणी में जुड़ा हुआ है)।
थिलो

1

स्वीकृत उत्तर सभी को इंगित करता है कि दोनों के बीच तथाकथित अंतर वास्तव में महत्वपूर्ण नहीं है।

यदि "एक पंक्ति को दो बार पुनर्प्राप्त किया जाता है और पंक्ति के भीतर मान रीड के बीच भिन्न होते हैं", तो वे एक ही पंक्ति नहीं हैं (सही RDB में एक ही ट्यूपल नहीं बोलते हैं) और यह वास्तव में परिभाषा के अनुसार भी मामला है कि "संग्रह दूसरी क्वेरी द्वारा लौटाई गई पंक्तियाँ पहले से अलग हैं "।

जैसा कि सवाल "किस अलगाव स्तर का उपयोग किया जाना चाहिए", जितना अधिक आपका डेटा किसी के लिए महत्वपूर्ण महत्व रखता है, कहीं न कहीं, यह उतना ही अधिक होगा कि Serializable आपका एकमात्र उचित विकल्प है।


0

मुझे लगता है कि गैर-दोहराने योग्य-पढ़ने और प्रेत-पढ़ने के बीच कुछ अंतर हैं।

गैर-दोहराए जाने वाले साधनों का मतलब है कि अगर कोई बी संशोधन कर सकता है तो ए और बी को टो लेनदेन ए और बी हो सकता है, इसलिए हो सकता है कि गंदा-पढ़ा जाए, इसलिए हम बी को ए के संशोधन के बाद नोटिस करते हैं।

नया मुद्दा है: हम B को A करने के बाद A के संशोधन की सूचना देते हैं, इसका अर्थ है A, पंक्ति का मान संशोधित करता है जिसे B धारण कर रहा है, कुछ समय बाद B पंक्ति को फिर से पढ़ेगा, इसलिए B को पहली बार के साथ नया मान अलग मिलेगा प्राप्त करें, हम इसे गैर-दोहराने योग्य कहते हैं, समस्या से निपटने के लिए, हम बी को कुछ याद करते हैं (क्योंकि मुझे नहीं पता है कि बी क्या याद किया जाएगा) जब बी शुरू होता है।

आइए नए समाधान के बारे में सोचते हैं, हम नोटिस कर सकते हैं कि नया मुद्दा भी है, क्योंकि हम बी को कुछ याद करते हैं, इसलिए जो कुछ भी ए में हुआ, बी प्रभावित नहीं हो सकता है, लेकिन अगर बी तालिका और बी में कुछ डेटा डालना चाहते हैं। यह सुनिश्चित करने के लिए तालिका की जांच करें कि कोई रिकॉर्ड नहीं है, लेकिन यह डेटा ए द्वारा डाला गया है, इसलिए शायद कुछ त्रुटि हो। इसे हम प्रेत-पाठ कहते हैं।


0

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

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