Erlang 21 - 5. Transactions and Other Access Contexts

5 लेन-देन और अन्य पहुँच संदर्भ




erlang

5 लेन-देन और अन्य पहुँच संदर्भ

इस खंड में Mnesia लेनदेन प्रणाली और लेनदेन गुणों का वर्णन किया गया है जो Mnesia एक सहिष्णु, वितरित डेटाबेस प्रबंधन प्रणाली (DBMS) Mnesia है।

यह खंड लॉकिंग फ़ंक्शन का भी वर्णन करता है, जिसमें टेबल लॉक और स्टिकी लॉक शामिल हैं, साथ ही वैकल्पिक फ़ंक्शन जो बेहतर गति और कम ओवरहेड के पक्ष में लेनदेन प्रणाली को बायपास करते हैं। इन कार्यों को "गंदा संचालन" कहा जाता है। नेस्टेड लेनदेन का उपयोग भी वर्णित है। निम्नलिखित विषयों में शामिल हैं:

  • लेन-देन के गुण, जिसमें परमाणु, संगति, अलगाव और स्थायित्व शामिल हैं
  • लॉक करना
  • गंदे ऑपरेशन
  • रिकॉर्ड नाम बनाम टेबल के नाम
  • गतिविधि की अवधारणा और विभिन्न पहुंच संदर्भ
  • नेस्टेड लेनदेन
  • पैटर्न मिलान
  • यात्रा

5.1 लेनदेन गुण

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

निम्नलिखित उदाहरण एक लेनदेन दिखाता है जो कुछ कर्मचारी संख्याओं के वेतन को बढ़ाता है:

raise(Eno, Raise) ->
    F = fun() ->
                [E] = mnesia:read(employee, Eno, write),
                Salary = E#employee.salary + Raise,
                New = E#employee{salary = Salary},
                mnesia:write(New)
        end,
    mnesia:transaction(F).

फ़ंक्शन raise/2 में चार कोड लाइनों से बना एक फ़न होता है। इस फन को स्टेटमेंट mnesia:transaction(F) कहा जाता है और वैल्यू देता है।

Mnesia लेनदेन प्रणाली निम्नलिखित महत्वपूर्ण गुण प्रदान करके विश्वसनीय, वितरित प्रणालियों के निर्माण की सुविधा प्रदान करती है:

  • लेन-देन करने वाला सुनिश्चित करता है कि एक फन, जिसे एक लेन-देन के अंदर रखा गया है, यह तालिकाओं पर संचालन की एक श्रृंखला को निष्पादित करते समय अन्य लेनदेन में एम्बेडेड संचालन में हस्तक्षेप नहीं करता है।
  • लेन-देन करने वाला सुनिश्चित करता है कि या तो लेन-देन में सभी ऑपरेशन परमाणु रूप से सभी नोड्स पर सफलतापूर्वक किए जाते हैं, या किसी भी नोड पर स्थायी प्रभाव के बिना लेनदेन विफल हो जाता है।
  • Mnesia लेनदेन में चार महत्वपूर्ण गुण हैं, जिन्हें टामिसिटी, सी ऑन्सिस्टेंसी, आई सॉल्यूशन, और डी यूरेबिलिटी (एसीआईडी) कहा जाता है। इन गुणों का वर्णन निम्नलिखित वर्गों में किया गया है।

atomicity

एटमॉसिटी का अर्थ है कि एक लेनदेन द्वारा निष्पादित किए जाने वाले डेटाबेस परिवर्तन सभी शामिल नोड्स या किसी भी नोड पर प्रभावी होते हैं। यही है, लेनदेन या तो पूरी तरह से सफल होता है, या यह पूरी तरह से विफल हो जाता है।

जब एक ही लेन-देन में एक से अधिक रिकॉर्ड को लिखने की आवश्यकता होती है तो एटमॉसिटी महत्वपूर्ण होती है। फ़ंक्शन raise/2 , पिछले उदाहरण में दिखाया गया है, केवल एक रिकॉर्ड लिखता है। फ़ंक्शन insert_emp/3 , Getting Started में प्रोग्राम लिस्टिंग में दिखाया गया है, रिकॉर्ड employee साथ-साथ कर्मचारी संबंध, जैसे at_dep और in_proj , डेटाबेस में in_proj । यदि यह बाद वाला कोड किसी लेनदेन के अंदर चलाया जाता है, तो लेन-देन करने वाला सुनिश्चित करता है कि लेनदेन या तो पूरी तरह से सफल होता है, या बिल्कुल भी नहीं।

Mnesia एक वितरित डीबीएमएस है जहां डेटा को कई नोड्स पर दोहराया जा सकता है। कई अनुप्रयोगों में, यह महत्वपूर्ण है कि लेखन कार्यों की एक श्रृंखला को एक लेनदेन के अंदर परमाणु रूप से निष्पादित किया जाता है। एटमॉसिटी संपत्ति यह सुनिश्चित करती है कि लेनदेन सभी नोड्स पर प्रभाव डालता है, या कोई भी नहीं।

संगति

स्थिरता संपत्ति यह सुनिश्चित करती है कि एक लेनदेन हमेशा एक सुसंगत स्थिति में DBMS छोड़ देता है। उदाहरण के लिए, Mnesia सुनिश्चित करता है कि कोई भी विसंगति तब न हो अगर Mnesia , Mnesia , या कंप्यूटर क्रैश हो जाता है जबकि एक Mnesia ऑपरेशन चल रहा है।

अलगाव

अलगाव की संपत्ति यह सुनिश्चित करती है कि एक नेटवर्क में विभिन्न नोड्स पर निष्पादित लेनदेन, और एक ही डेटा रिकॉर्ड तक पहुंच और हेरफेर करें, एक दूसरे के साथ हस्तक्षेप न करें। आइसोलेशन प्रॉपर्टी फ़ंक्शन को समवर्ती raise/2 समवर्ती रूप से निष्पादित करना संभव बनाता है। संगामिति नियंत्रण सिद्धांत में एक शास्त्रीय समस्या "खोई हुई अद्यतन समस्या" है।

अलगाव की संपत्ति विशेष रूप से उपयोगी है यदि निम्न परिस्थितियां होती हैं जहां एक कर्मचारी (कर्मचारी संख्या 123 के साथ) और दो प्रक्रियाएं (पी 1 और पी 2) समवर्ती रूप से कर्मचारी के लिए वेतन बढ़ाने की कोशिश कर रहे हैं:

  • चरण 1: कर्मचारियों के वेतन का प्रारंभिक मूल्य, उदाहरण के लिए, 5. प्रक्रिया P1 निष्पादित करना शुरू करता है, कर्मचारी रिकॉर्ड पढ़ता है, और वेतन में 2 जोड़ता है।
  • चरण 2: प्रक्रिया पी 1 किसी कारण से पूर्व-खाली है और प्रक्रिया पी 2 को चलाने का अवसर है।
  • चरण 3: प्रोसेस पी 2 रिकॉर्ड पढ़ता है, वेतन में 3 जोड़ता है, और अंत में 8 के वेतन के साथ एक नया कर्मचारी रिकॉर्ड लिखता है।
  • चरण 4: प्रक्रिया पी 1 फिर से चलना शुरू कर देता है और अपने कर्मचारी रिकॉर्ड को वेतन सेट के साथ 7 पर लिखता है, इस प्रकार प्रभावी ढंग से ओवरराइटिंग और प्रक्रिया पी 2 द्वारा निष्पादित कार्य को पूर्ववत करता है। P2 द्वारा किया गया अद्यतन खो जाता है।

एक लेनदेन प्रणाली दो या दो से अधिक प्रक्रियाओं को समवर्ती रूप से निष्पादित करना संभव बनाती है जो समान रिकॉर्ड में हेरफेर करती है। प्रोग्रामर को यह जांचने की आवश्यकता नहीं है कि अपडेट समकालिक हैं; यह लेन-देन करने वाले की देखरेख करता है। लेन-देन प्रणाली के माध्यम से डेटाबेस तक पहुंचने वाले सभी कार्यक्रमों को लिखा जा सकता है जैसे कि उनके पास डेटा तक पहुंच थी।

सहनशीलता

स्थायित्व संपत्ति सुनिश्चित करती है कि लेनदेन द्वारा DBMS में किए गए परिवर्तन स्थायी हैं। एक बार लेन-देन करने के बाद, डेटाबेस में किए गए सभी परिवर्तन टिकाऊ होते हैं, अर्थात वे डिस्क पर सुरक्षित रूप से लिखे जाते हैं और दूषित नहीं होते हैं और गायब नहीं होते हैं।

ध्यान दें

वर्णित स्थायित्व सुविधा पूरी तरह से उन स्थितियों पर लागू नहीं होती है जहां Mnesia को "शुद्ध" प्राथमिक मेमोरी डेटाबेस के रूप में कॉन्फ़िगर किया गया है।

5.2 ताला लगाना

अलग-अलग लेन-देन प्रबंधक अलगाव की संपत्ति को संतुष्ट करने के लिए अलग-अलग रणनीतियों को नियुक्त करते हैं। Mnesia दो चरण लॉकिंग की मानक तकनीक का उपयोग करता है। यानी, पढ़ने या लिखे जाने से पहले रिकॉर्ड पर ताले लगा दिए जाते हैं। Mnesia निम्नलिखित लॉक प्रकारों का उपयोग करता है:

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

Mnesia एक रणनीति को Mnesia करता है, जिसमें mnesia:read/1 जैसे कार्य mnesia:read/1 लेनदेन को निष्पादित करते समय गतिशील रूप से आवश्यक ताले को mnesia:read/1 प्राप्त करें। Mnesia स्वचालित रूप से ताले को सेट और रिलीज करता है और प्रोग्रामर को इन ऑपरेशनों को कोड करने की आवश्यकता नहीं है।

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

इसलिए यह महत्वपूर्ण है कि mnesia:transaction/1 को दिए गए फन के अंदर का कोड mnesia:transaction/1 शुद्ध हो। कुछ अजीब परिणाम हो सकते हैं यदि, उदाहरण के लिए, लेन-देन द्वारा संदेश भेजे जाते हैं मज़ा। निम्न उदाहरण इस स्थिति को दर्शाता है:

bad_raise(Eno, Raise) ->
    F = fun() ->
                [E] = mnesia:read({employee, Eno}),
                Salary = E#employee.salary + Raise,
                New = E#employee{salary = Salary},
                io:format("Trying to write ... ~n", []),
                mnesia:write(New)
        end,
    mnesia:transaction(F).

यह लेनदेन "Trying to write ... " लिखने की "Trying to write ... " पाठ को टर्मिनल से 1000 गुना "Trying to write ... " । हालांकि, Mnesia गारंटी देता है कि प्रत्येक लेनदेन अंततः चलेगा। नतीजतन, Mnesia न केवल गतिरोध मुक्त है, बल्कि Mnesia मुक्त भी है।

Mnesia प्रोग्रामर किसी अन्य लेनदेन से पहले निष्पादित करने के लिए एक विशेष लेनदेन को प्राथमिकता नहीं दे सकता है जो निष्पादित करने के लिए इंतजार कर रहे हैं। नतीजतन, Mnesia DBMS लेनदेन प्रणाली कठिन वास्तविक समय अनुप्रयोगों के लिए उपयुक्त नहीं है। हालांकि, Mnesia में अन्य विशेषताएं शामिल हैं जिनमें वास्तविक समय गुण हैं।

Mnesia गतिशील रूप से सेट करता है और लेनदेन निष्पादित करते हुए ताले जारी करता है। इसलिए लेन-देन के दुष्प्रभावों के साथ कोड निष्पादित करना खतरनाक है। विशेष रूप से, लेन-देन के अंदर एक receive बयान एक ऐसी स्थिति का कारण बन सकता है जहां लेनदेन लटका रहता है और कभी नहीं लौटता है, जिसके कारण ताले जारी नहीं कर सकते हैं। यह स्थिति पूरे सिस्टम को एक ठहराव में ला सकती है, क्योंकि अन्य लेनदेन या अन्य नोड्स पर निष्पादित होने वाले अन्य लेनदेन को दोषपूर्ण लेनदेन के लिए इंतजार करने के लिए मजबूर किया जाता है।

यदि कोई लेन-देन असामान्य रूप से समाप्त हो जाता है, तो Mnesia स्वचालित रूप से लेनदेन द्वारा रखे गए ताले को छोड़ देता है।

अब तक, एक लेनदेन के अंदर उपयोग किए जा सकने वाले कई कार्यों के उदाहरण दिखाए गए हैं। निम्नलिखित सूची सरलतम Mnesia कार्यों को Mnesia है जो लेनदेन के साथ काम करते हैं। ध्यान दें कि इन कार्यों को लेनदेन में एम्बेड किया जाना चाहिए। यदि कोई संलग्न लेनदेन (या अन्य गतिविधि Mnesia गतिविधि) मौजूद नहीं है, तो वे सभी विफल हो जाते हैं।

  • mnesia:transaction/1 एकल पैरामीटर के रूप में कार्यात्मक वस्तु Fun साथ एक लेनदेन को निष्पादित करता है।
  • mnesia:read/1 mnesia:read/1 तालिका Tab से Key रूप में कुंजी के साथ सभी रिकॉर्ड पढ़ता है। इस फ़ंक्शन में Table के स्थान की परवाह किए बिना एक ही शब्दार्थ है। यदि तालिका प्रकार bag , तो read({Tab, Key}) एक मनमाने ढंग से लंबी सूची वापस कर सकता है। यदि तालिका प्रकार set , तो सूची लंबाई एक या []
  • mnesia:wread({Tab, Key}) -> transaction abort | RecordList mnesia:wread({Tab, Key}) -> transaction abort | RecordList उसी तरह व्यवहार करता है जैसे पहले सूचीबद्ध फ़ंक्शन read/1 , सिवाय इसके कि वह रीड लॉक के बजाय राइट लॉक प्राप्त करता है। एक रिकॉर्ड को पढ़ने वाले लेनदेन को निष्पादित करने के लिए, रिकॉर्ड को संशोधित करता है, और फिर रिकॉर्ड को लिखता है, यह राइट लॉक को तुरंत सेट करने के लिए थोड़ा अधिक कुशल है। जब एक mnesia:read/1 जारी किया जाता है, उसके बाद mnesia:write/1 पहले रीड लॉक को राइट लॉक में अपग्रेड किया जाना चाहिए जब राइट ऑपरेशन निष्पादित किया जाता है।
  • mnesia:write/1 mnesia:write/1 डेटाबेस में एक रिकॉर्ड लिखता है। तर्क Record एक Record का एक उदाहरण है। यदि कोई त्रुटि होती है, तो फ़ंक्शन ok लौटता है, या लेनदेन को समाप्त करता है।
  • mnesia:delete({Tab, Key}) -> transaction abort | ok mnesia:delete({Tab, Key}) -> transaction abort | ok दिए गए कुंजी के साथ सभी रिकॉर्ड हटाता है।
  • mnesia:delete_object(Record) -> transaction abort | ok OID रिकॉर्ड के साथ रिकॉर्ड हटाता है। प्रकार के bag में केवल कुछ रिकॉर्ड को हटाने के लिए इस फ़ंक्शन का उपयोग करें।

चिपचिपा ताले

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

एक चिपचिपा ताला एक ताला है जो एक नोड पर जगह में रहता है, लेन-देन के बाद जिसने पहले ताला का अधिग्रहण किया है वह समाप्त हो गया है। इसे समझने के लिए, मान लें कि निम्नलिखित लेन-देन निष्पादित है:

F = fun() ->
      mnesia:write(#foo{a = kalle})
    end,
mnesia:transaction(F).

foo तालिका दो नोड्स N1 और N2 पर दोहराई जाती है।

सामान्य लॉकिंग के लिए निम्नलिखित की आवश्यकता होती है:

  • राइट लॉक हासिल करने के लिए एक नेटवर्क आरपीसी (दो संदेश)
  • दो-चरण प्रतिबद्ध प्रोटोकॉल को निष्पादित करने के लिए तीन नेटवर्क संदेश

यदि चिपचिपे ताले का उपयोग किया जाता है, तो कोड को पहले निम्नानुसार बदलना चाहिए:

F = fun() ->
      mnesia:s_write(#foo{a = kalle})
    end,
mnesia:transaction(F).

यह कोड फ़ंक्शन mnesia:write/1 बजाय फ़ंक्शन s_write/1 का उपयोग करता है mnesia:write/1 फ़ंक्शन s_write/1 सामान्य लॉक के बजाय एक चिपचिपा लॉक सेट करता है। यदि तालिका को दोहराया नहीं जाता है, तो चिपचिपा ताले का कोई विशेष प्रभाव नहीं होता है। यदि तालिका को दोहराया जाता है, और नोड N1 पर एक चिपचिपा लॉक सेट किया जाता है, तो यह लॉक तब नोड N1 से चिपक जाता है। अगली बार जब आप नोड N1 पर एक ही रिकॉर्ड पर एक चिपचिपा लॉक सेट करने का प्रयास करते हैं, Mnesia पता लगाता है कि लॉक पहले से ही सेट है और लॉक प्राप्त करने के लिए कोई नेटवर्क ऑपरेशन नहीं करता है।

यह एक स्थानीय लॉक सेट करने के लिए अधिक कुशल है जितना कि एक नेटवर्क लॉक सेट करना है। इसलिए स्टिकी ताले एक एप्लिकेशन को लाभ दे सकते हैं जो एक प्रतिकृति तालिका का उपयोग करता है और केवल एक नोड पर अधिकांश कार्य करता है।

यदि कोई रिकॉर्ड नोड N1 पर अटका हुआ है और आप नोड N2 पर रिकॉर्ड के लिए एक चिपचिपा लॉक सेट करने का प्रयास करते हैं, तो रिकॉर्ड को अनस्टुक होना चाहिए। यह ऑपरेशन महंगा है और प्रदर्शन को कम करता है। यदि आप N2 पर s_write/1 अनुरोध जारी करते हैं, तो s_write/1 स्वचालित रूप से हो जाती है।

टेबल ताले

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

तालिका ताले के अधिग्रहण के लिए वैकल्पिक वाक्यविन्यास इस प्रकार है:

mnesia:lock({table, Tab}, read)
mnesia:lock({table, Tab}, write)

Mnesia में मिलान संचालन या तो पूरी तालिका को लॉक कर सकता है या केवल एक रिकॉर्ड (जब पैटर्न में कुंजी बंधी होती है)।

वैश्विक ताले

लिखें ताले आम तौर पर सभी नोड्स पर प्राप्त किए जाते हैं जहां तालिका की एक प्रतिकृति रहती है (और सक्रिय है)। पढ़ें एक नोड पर ताले प्राप्त किए जाते हैं (स्थानीय एक अगर एक स्थानीय प्रतिकृति मौजूद है)।

समारोह mnesia:lock/2 का उद्देश्य टेबल तालों का समर्थन करना है (जैसा कि पहले उल्लेख किया गया है) लेकिन उन स्थितियों के लिए भी जब तालों को दोहराया गया है, भले ही ताले को अधिग्रहित करने की आवश्यकता हो।

mnesia:lock({global, GlobalKey, Nodes}, LockKind)

LockKind ::= read | write | ...

नोड सूची में सभी नोड्स पर लॉक LockItem पर लॉक का अधिग्रहण किया गया है।

5.3 गंदे संचालन

कई अनुप्रयोगों में, लेनदेन के प्रसंस्करण के ओवरहेड के परिणामस्वरूप प्रदर्शन का नुकसान हो सकता है। डर्टी ऑपरेशन शॉर्ट कट्स होते हैं जो बहुत प्रसंस्करण को बाईपास करते हैं और लेनदेन की गति बढ़ाते हैं।

डर्टी ऑपरेशन अक्सर उपयोगी होते हैं, उदाहरण के लिए, डेटाग्राम रूटिंग एप्लिकेशन में जहां Mnesia राउटिंग टेबल को स्टोर करता है, और एक पैकेट प्राप्त होने पर हर बार पूरे लेनदेन को शुरू करने में समय लगता है। Mnesia ऐसे कार्य होते हैं जो लेनदेन का उपयोग किए बिना तालिकाओं में हेरफेर करते हैं। प्रसंस्करण के इस विकल्प को एक गंदे संचालन के रूप में जाना जाता है। हालाँकि, लेन-देन प्रसंस्करण के ओवरहेड से बचने में ट्रेड-ऑफ पर ध्यान दें:

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

गंदे संचालन का प्रमुख लाभ यह है कि वे समान संचालन की तुलना में बहुत तेजी से निष्पादित होते हैं जो लेनदेन के भीतर कार्यात्मक वस्तुओं के रूप में संसाधित होते हैं।

गंदे संचालन डिस्क के लिए लिखे जाते हैं यदि वे प्रकार की तालिका पर किए जाते हैं disc_copies या disc_only_copies Mnesia यह भी सुनिश्चित करता है कि यदि टेबल पर गंदा लेखन ऑपरेशन किया जाता है, तो तालिका के सभी प्रतिकृतियां अपडेट की जाती हैं।

एक गंदा ऑपरेशन एक निश्चित स्तर की स्थिरता सुनिश्चित करता है। उदाहरण के लिए, गंदे संचालन वापस रिकॉर्ड किए गए नहीं कर सकते। इसलिए, प्रत्येक व्यक्ति पढ़ने या लिखने का संचालन परमाणु तरीके से किया जाता है।

सभी गंदे कार्य विफलता पर exit({aborted, Reason}) कॉल को निष्पादित करते हैं। यहां तक ​​कि अगर निम्नलिखित कार्यों को एक लेनदेन के अंदर निष्पादित किया जाता है, तो कोई लॉक हासिल नहीं किया जाता है। निम्नलिखित कार्य उपलब्ध हैं:

  • mnesia:dirty_read({Tab, Key}) एक या अधिक रिकॉर्ड पढ़ता है।
  • mnesia:dirty_write(Record) रिकॉर्ड Record लिखता है।
  • mnesia:dirty_delete({Tab, Key}) कुंजी के साथ एक या अधिक रिकॉर्ड हटाता है।
  • mnesia:dirty_delete_object(Record) फ़ंक्शन delete_object/1 का गंदा ऑपरेशन विकल्प है।
  • mnesia:dirty_first(Tab) टेबल Tab में "पहली" कुंजी देता है।

    set या bag टेबल में रिकॉर्ड छांटे नहीं गए हैं। हालांकि, एक रिकॉर्ड ऑर्डर है जो उपयोगकर्ता के लिए अज्ञात है। इसका मतलब यह है कि इस टेबल को फंक्शन mnesia:dirty_next/2 साथ ट्रेस किया जा सकता है mnesia:dirty_next/2

    यदि तालिका में कोई रिकॉर्ड नहीं हैं, तो यह फ़ंक्शन परमाणु को '$end_of_table' । यह किसी भी उपयोगकर्ता रिकॉर्ड के लिए कुंजी के रूप में इस परमाणु का उपयोग करने के लिए अनुशंसित नहीं है।

  • mnesia:dirty_next/2 टेबल Tab में "अगला" कुंजी देता है। यह फ़ंक्शन एक तालिका को पीछे करना और तालिका में सभी रिकॉर्ड पर कुछ ऑपरेशन करना संभव बनाता है। जब तालिका का अंत पहुँच जाता है, तो विशेष कुंजी '$end_of_table' वापस आ जाती है। अन्यथा, फ़ंक्शन एक कुंजी देता है जिसका उपयोग वास्तविक रिकॉर्ड पढ़ने के लिए किया जा सकता है।

    व्यवहार अपरिभाषित है यदि कोई भी कार्य फ़ंक्शन mnesia:dirty_next/2 साथ तालिका को ट्रैवर्स करते समय टेबल पर एक Mnesia ऑपरेशन करता है, ऐसा इसलिए है क्योंकि एक Mnesia तालिका पर write संचालन से तालिका के आंतरिक पुनर्गठन हो सकते हैं। यह एक कार्यान्वयन विवरण है, लेकिन याद रखें कि गंदे कार्य निम्न स्तर के कार्य हैं।

  • mnesia:dirty_last(Tab) बिल्कुल mnesia:dirty_first(Tab) तरह काम करता है mnesia:dirty_first(Tab) लेकिन टेबल प्रकार के ordered_set शब्द क्रम में अंतिम वस्तु देता है। अन्य सभी प्रकार की mnesia:dirty_first/1 , mnesia:dirty_first/1 और mnesia:dirty_last/1 पर्यायवाची शब्द हैं।
  • mnesia:dirty_prev(Tab, Key) बिल्कुल mnesia:dirty_next/2 तरह काम करती है mnesia:dirty_next/2 लेकिन तालिका प्रकार ordered_set लिए Erlang शब्द क्रम में पिछली वस्तु वापस ordered_set । अन्य सभी प्रकार की mnesia:dirty_next/2 , mnesia:dirty_next/2 और mnesia:dirty_prev/2 पर्यायवाची हैं।
  • mnesia:dirty_slot(Tab, Slot) रिकॉर्ड्स की सूची लौटाता है जो एक तालिका में Slot जुड़े हैं। इसका उपयोग फ़ंक्शन dirty_next/2 समान तरीके से तालिका को पार करने के लिए किया जा सकता है। एक टेबल में कई स्लॉट होते हैं जो शून्य से लेकर कुछ अज्ञात ऊपरी सीमा तक होते हैं। तालिका के अंत तक पहुंचने पर फ़ंक्शन dirty_slot/2 विशेष परमाणु '$end_of_table' है।

    इस कार्य का व्यवहार अपरिभाषित है, यदि तालिका का पता लगाया जा रहा है। फ़ंक्शन mnesia:read_lock_table(Tab) का उपयोग यह सुनिश्चित करने के लिए किया जा सकता है कि पुनरावृत्ति के दौरान कोई लेनदेन-संरक्षित लेखन नहीं किया जाता है।

  • mnesia:dirty_update_counter({Tab,Key}, Val) । काउंटर सकारात्मक पूर्णांक हैं जिनका मान शून्य से अधिक या उसके बराबर है। एक काउंटर को अपडेट करना Val जोड़ता है और वह काउंटर जहां Val एक सकारात्मक या नकारात्मक पूर्णांक है।

    Mnesia पास कोई विशेष काउंटर रिकॉर्ड नहीं है। हालाँकि, प्रपत्र {TabName, Key, Integer} रिकॉर्ड का उपयोग काउंटर के रूप में किया जा सकता है, और यह निरंतर हो सकता है।

    काउंटर रिकॉर्ड्स का लेन-देन-संरक्षित अद्यतन संभव नहीं है।

    रिकॉर्ड को पढ़ने, अंकगणित करने और रिकॉर्ड लिखने के बजाय इस फ़ंक्शन का उपयोग करते समय दो महत्वपूर्ण अंतर हैं:

    • यह बहुत अधिक कुशल है।
    • dirty_update_counter/2 परमाणु कार्रवाई के रूप में किया जाता है, हालांकि यह एक लेनदेन द्वारा संरक्षित नहीं है। यदि कोई प्रक्रिया दो कार्य एक साथ dirty_update_counter/2 निष्पादित करती है, तो कोई तालिका अद्यतन नहीं dirty_update_counter/2
  • mnesia:dirty_match_object(Pat) का गंदा समान है mnesia:match_object/1
  • mnesia:dirty_select(Tab, Pat) mnesia:select/2 का गंदा समान है mnesia:select/2
  • mnesia:dirty_index_match_object(Pat, Pos) mnesia:index_match_object/2 का गंदा समकक्ष है mnesia:index_match_object/2
  • mnesia:dirty_index_read(Tab, SecondaryKey, Pos) mnesia:index_read/3 का गंदा समान है mnesia:index_read/3
  • mnesia:dirty_all_keys(Tab) का गंदा समान है mnesia:all_keys/1

5.4 रिकॉर्ड नाम बनाम टेबल नाम

Mnesia , एक तालिका में सभी रिकॉर्ड एक ही नाम होना चाहिए। सभी रिकॉर्ड एक ही रिकॉर्ड प्रकार के उदाहरण होने चाहिए। हालाँकि, रिकॉर्ड नाम, जरूरी नहीं कि तालिका नाम के समान हो, हालाँकि इस उपयोगकर्ता की मार्गदर्शिका में अधिकांश उदाहरणों में यही स्थिति है। यदि कोई संपत्ति गुण record_name के बिना तालिका बनाई record_name , तो निम्न कोड सुनिश्चित करता है कि तालिकाओं में सभी रिकॉर्ड तालिका के समान नाम हैं:

mnesia:create_table(subscriber, [])

हालाँकि, यदि तालिका को तर्क के रूप में एक स्पष्ट रिकॉर्ड नाम के साथ बनाया गया है, जैसा कि निम्नलिखित उदाहरण में दिखाया गया है, टेबल के नामों की परवाह किए बिना, दोनों में ग्राहक रिकॉर्ड संग्रहीत किए जा सकते हैं:

TabDef = [{record_name, subscriber}],
mnesia:create_table(my_subscriber, TabDef),
mnesia:create_table(your_subscriber, TabDef).

ऐसी तालिकाओं का उपयोग करने के लिए, सरलीकृत पहुंच कार्यों (जैसा कि पहले बताया गया है) का उपयोग नहीं किया जा सकता है। उदाहरण के लिए, एक तालिका में एक ग्राहक रिकॉर्ड लिखने के लिए फ़ंक्शन mnesia:write/3 आवश्यकता होती है mnesia:write/3 सरलीकृत कार्यों के बजाय mnesia:write/3 mnesia:write/1 और s_write/1 :

mnesia:write(subscriber, #subscriber{}, write)
mnesia:write(my_subscriber, #subscriber{}, sticky_write)
mnesia:write(your_subscriber, #subscriber{}, write)

निम्नलिखित सरल कोड अधिकांश उदाहरणों और उनके अधिक लचीले समकक्षों में उपयोग किए जाने वाले सरलीकृत पहुंच कार्यों के बीच के संबंध को दर्शाता है:

mnesia:dirty_write(Record) ->
  Tab = element(1, Record),
  mnesia:dirty_write(Tab, Record).

mnesia:dirty_delete({Tab, Key}) ->
  mnesia:dirty_delete(Tab, Key).

mnesia:dirty_delete_object(Record) ->
  Tab = element(1, Record),
  mnesia:dirty_delete_object(Tab, Record) 

mnesia:dirty_update_counter({Tab, Key}, Incr) ->
  mnesia:dirty_update_counter(Tab, Key, Incr).

mnesia:dirty_read({Tab, Key}) ->
  Tab = element(1, Record),
  mnesia:dirty_read(Tab, Key).

mnesia:dirty_match_object(Pattern) ->
  Tab = element(1, Pattern),
  mnesia:dirty_match_object(Tab, Pattern).

mnesia:dirty_index_match_object(Pattern, Attr) 
  Tab = element(1, Pattern),
  mnesia:dirty_index_match_object(Tab, Pattern, Attr).

mnesia:write(Record) ->
  Tab = element(1, Record),
  mnesia:write(Tab, Record, write).

mnesia:s_write(Record) ->
  Tab = element(1, Record),
  mnesia:write(Tab, Record, sticky_write).

mnesia:delete({Tab, Key}) ->
  mnesia:delete(Tab, Key, write).

mnesia:s_delete({Tab, Key}) ->
  mnesia:delete(Tab, Key, sticky_write).

mnesia:delete_object(Record) ->
  Tab = element(1, Record),
  mnesia:delete_object(Tab, Record, write).

mnesia:s_delete_object(Record) ->
  Tab = element(1, Record),
  mnesia:delete_object(Tab, Record, sticky_write).

mnesia:read({Tab, Key}) ->
  mnesia:read(Tab, Key, read).

mnesia:wread({Tab, Key}) ->
  mnesia:read(Tab, Key, write).

mnesia:match_object(Pattern) ->
  Tab = element(1, Pattern),
  mnesia:match_object(Tab, Pattern, read).

mnesia:index_match_object(Pattern, Attr) ->
  Tab = element(1, Pattern),
  mnesia:index_match_object(Tab, Pattern, Attr, read).

5.5 गतिविधि संकल्पना और विभिन्न पहुँच संदर्भ

जैसा कि पहले बताया गया है, एक कार्यात्मक वस्तु (मज़ा) प्रदर्शन तालिका अभिगम संचालन, जैसा कि यहाँ सूचीबद्ध है, को समारोह के तर्कों के रूप में पारित किया जा सकता है mnesia:transaction/1 :

ये कार्य एक लेनदेन के संदर्भ में किए जाते हैं, जिसमें तंत्र शामिल हैं, जैसे लॉकिंग, लॉगिंग, प्रतिकृति, चौकियों, सदस्यता और प्रतिबद्ध प्रोटोकॉल। हालांकि, एक ही फ़ंक्शन को अन्य गतिविधि संदर्भों में भी मूल्यांकन किया जा सकता है।

वर्तमान में निम्नलिखित गतिविधि पहुंच संदर्भ समर्थित हैं:

  • transaction
  • sync_transaction
  • async_dirty
  • sync_dirty
  • ets

फ़ंक्शन mnesia:sync_transaction(Fun [, Args]) तर्क के रूप में समान "मज़ेदार" पास करके mnesia:sync_transaction(Fun [, Args]) यह सिंक्रनाइज़ लेनदेन संदर्भ में किया जाता है। सिंक किए गए लेन-देन तब तक प्रतीक्षा करते हैं जब तक कि सभी सक्रिय प्रतिकृतियां mnesia:sync_transaction से लौटने से पहले लेन-देन (डिस्क करने के लिए) कर mnesia:sync_transaction कॉल। निम्नलिखित मामलों में sync_transaction का उपयोग करना उपयोगी है:

  • जब कोई एप्लिकेशन कई नोड्स पर कार्यान्वित होता है और यह सुनिश्चित करना चाहता है कि रिमोट प्रक्रिया को अपडेट करने से पहले रिमोट नोड्स पर अपडेट किया जाता है या किसी दूरस्थ प्रक्रिया को संदेश भेजा जाता है।
  • जब एक संयोजन लेनदेन "गंदे_ धागे" के साथ लिखते हैं, dirty_read , फ़ंक्शन dirty_match_object , dirty_read , dirty_index_read , dirty_select , और इसी तरह।
  • जब कोई एप्लिकेशन लगातार या Mnesia अपडेट करता है जो अन्य नोड्स पर Mnesia को अधिभार कर सकता है।

फ़ंक्शन mnesia:async_dirty(Fun [, Args]) तर्क के रूप में एक ही "मज़ा" पारित करके, इसे गंदे संदर्भ में किया जाता है। फ़ंक्शन कॉल संबंधित गंदे कार्यों के लिए मैप किए जाते हैं। इसमें अभी भी लॉगिंग, प्रतिकृति और सदस्यता शामिल हैं लेकिन कोई लॉकिंग, स्थानीय लेनदेन भंडारण या प्रतिबद्ध प्रोटोकॉल शामिल नहीं हैं। चेकपॉइंट अनुचर अपडेट किए जाते हैं लेकिन "गंदे" अपडेट किए जाते हैं। इस प्रकार, उन्हें एसिंक्रोनस रूप से अपडेट किया जाता है। फ़ंक्शन एक नोड पर प्रदर्शन किए जाने के लिए प्रतीक्षा करते हैं, लेकिन अन्य नहीं। यदि तालिका स्थानीय रूप से रहती है, तो कोई प्रतीक्षा नहीं होती है।

फ़ंक्शन mnesia:sync_dirty(Fun [, Args]) लिए एक तर्क के रूप में उसी "मज़े" को पास करके mnesia:sync_dirty(Fun [, Args]) , यह फ़ंक्शन mnesia:async_dirty/1,2 के समान लगभग संदर्भ में किया mnesia:async_dirty/1,2 । अंतर यह है कि संचालन समकालिक रूप से किया जाता है। कॉलर सभी सक्रिय प्रतिकृतियों पर किए जाने वाले अद्यतनों की प्रतीक्षा करता है। mnesia:sync_dirty/1,2 का उपयोग करना mnesia:sync_dirty/1,2 निम्नलिखित मामलों में mnesia:sync_dirty/1,2 उपयोगी है:

  • जब कोई एप्लिकेशन कई नोड्स पर कार्यान्वित होता है और यह सुनिश्चित करना चाहता है कि रिमोट प्रक्रिया को अपडेट करने से पहले रिमोट नोड्स पर अपडेट किया जाता है या किसी दूरस्थ प्रक्रिया को संदेश भेजा जाता है।
  • जब कोई एप्लिकेशन लगातार या Mnesia अपडेट करता है जो नोड्स पर Mnesia को Mnesia कर सकता है।

यह जांचने के लिए कि क्या आपका कोड किसी लेन-देन के भीतर mnesia:is_transaction/0 गया है, फ़ंक्शन mnesia:is_transaction/0 उपयोग करें mnesia:is_transaction/0 । लेन-देन के संदर्भ में कहा जाए तो यह true है, अन्यथा false

भंडारण प्रकार RAM_copies और disc_copies साथ Mnesia तालिकाओं को आंतरिक रूप से ets तालिकाओं के रूप में कार्यान्वित किया जाता है। एप्लिकेशन इन तालिकाओं को सीधे एक्सेस कर सकते हैं। यह केवल तभी अनुशंसित किया जाता है जब सभी विकल्पों को तौला गया हो और संभावित परिणामों को समझा जाए। फ़ंक्शन mnesia:ets(Fun [, Args]) के पहले उल्लिखित "मज़े" को पारित करके, यह एक कच्चे संदर्भ में किया जाता है। ऑपरेशन स्थानीय ets टेबल पर सीधे किए जाते हैं, यह मानते हुए कि स्थानीय भंडारण प्रकार RAM_copies और तालिका अन्य नोड्स पर प्रतिकृति नहीं है।

सदस्यता को ट्रिगर नहीं किया जाता है और कोई भी चौकियों को अपडेट नहीं किया जाता है, लेकिन यह ऑपरेशन तेजी से अंधाधुंध है। डिस्क के अपडेट नहीं होने से डिस्क रेजिडेंट टेबल को ets फंक्शन से अपडेट नहीं किया जाना है।

फन को फंक्शन mnesia:activity/2,3,4 एक तर्क के रूप में भी पास किया जा सकता है mnesia:activity/2,3,4 , जो कस्टमाइज्ड एक्टिविटी एक्सेस कॉलबैक मॉड्यूल के उपयोग को सक्षम करता है। यह या तो सीधे मॉड्यूल नाम को तर्क के रूप में बताकर प्राप्त किया जा सकता है, या कॉन्फ़िगरेशन पैरामीटर access_module उपयोग से प्राप्त किया जा सकता है। एक अनुकूलित कॉलबैक मॉड्यूल का उपयोग कई उद्देश्यों के लिए किया जा सकता है, जैसे ट्रिगर, अखंडता अवरोध, रनटाइम आँकड़े या वर्चुअल टेबल प्रदान करना।

कॉलबैक मॉड्यूल को असली Mnesia तालिकाओं तक पहुंचने की आवश्यकता नहीं है, यह तब तक करने के लिए स्वतंत्र है जब तक कॉलबैक इंटरफ़ेस पूरा नहीं होता है।

Appendix B, Activity Access Callback Interface एक वैकल्पिक कार्यान्वयन के लिए स्रोत कोड, mnesia_frag.erl प्रदान करता है। प्रसंग-संवेदी फ़ंक्शन mnesia:table_info/2 का उपयोग किसी तालिका के बारे में वर्चुअल जानकारी प्रदान करने के लिए किया जा सकता है। इसका एक उपयोग एक कस्टमाइज़्ड कॉलबैक मॉड्यूल के साथ गतिविधि के संदर्भ में QLC प्रश्न करना है। टेबल इंडेक्स और अन्य QLC आवश्यकताओं के बारे में तालिका जानकारी प्रदान करके, QLC को वर्चुअल टेबल तक पहुंचने के लिए एक सामान्य क्वेरी भाषा के रूप में उपयोग किया जा सकता है।

इन सभी गतिविधि संदर्भों ( transaction , sync_transaction , async_dirty , sync_dirty , और ets ) में sync_dirty प्रश्न किए जा सकते हैं। यदि तालिका में कोई अनुक्रमणिका नहीं है, तो ets गतिविधि केवल काम करती है।

ध्यान दें

फंक्शन mnesia:dirty_* हमेशा async_dirty साथ निष्पादित होते हैं, भले ही एक्टिविटी एक्सेस संदर्भ जो शुरू हो गए हों। यह भी किसी भी गतिविधि गतिविधि संदर्भ संलग्न बिना संदर्भ शुरू कर सकते हैं।

5.6 नेस्टेड लेनदेन

लेनदेन एक मनमाने ढंग से किया जा सकता है। एक बच्चे के लेन-देन को उसके माता-पिता के समान प्रक्रिया में चलना चाहिए। जब एक बच्चा लेनदेन समाप्त हो जाता है, तो बाल लेनदेन के कॉलर को रिटर्न वैल्यू {aborted, Reason} मिलती है और बच्चे द्वारा किए गए किसी भी कार्य को मिटा दिया जाता है। यदि कोई बच्चा लेन-देन करता है, तो बच्चे द्वारा लिखे गए रिकॉर्ड अभिभावक को प्रसारित किए जाते हैं।

बाल लेनदेन समाप्त होने पर कोई लॉक जारी नहीं किया जाता है। नेस्टेड लेनदेन के अनुक्रम द्वारा बनाए गए ताले तब तक रखे जाते हैं जब तक कि शीर्ष लेनदेन समाप्त नहीं हो जाता। इसके अलावा, नेस्टेड लेनदेन द्वारा किया गया कोई भी अपडेट केवल इस तरह से प्रचारित किया जाता है ताकि नेस्टेड लेनदेन के माता-पिता अपडेट को देखें। शीर्ष-स्तरीय लेनदेन समाप्त होने तक कोई अंतिम प्रतिबद्धता नहीं होती है। इसलिए, हालांकि एक नेस्टेड लेनदेन {atomic, Val} लौटाता है, यदि संलग्न माता-पिता लेनदेन समाप्त हो जाता है, तो पूरा नेस्टेड ऑपरेशन समाप्त हो जाता है।

शीर्ष स्तर के लेन-देन के रूप में समान शब्दार्थ के साथ नेस्टेड लेन-देन करने की क्षमता से लाइब्रेरी कार्यों को लिखना आसान हो जाता है जो Mnesia तालिकाओं में हेरफेर Mnesia

एक फ़ंक्शन पर विचार करें जो एक टेलीफ़ोनी सिस्टम के लिए एक ग्राहक जोड़ता है:

add_subscriber(S) ->
    mnesia:transaction(fun() ->
        case mnesia:read( ..........

इस फ़ंक्शन को लेनदेन के रूप में कहा जाना चाहिए। मान लें कि आप एक फ़ंक्शन लिखना चाहते हैं जो दोनों फ़ंक्शन add_subscriber/1 कॉल करता है और अपने आप में एक लेनदेन के संदर्भ द्वारा संरक्षित है। add_subscriber/1 को किसी अन्य लेनदेन के भीतर से कॉल करके, एक नेस्टेड लेनदेन बनाया जाता है।

साथ ही, घोंसले के शिकार के दौरान विभिन्न गतिविधि एक्सेस संदर्भों को मिलाया जा सकता है। हालाँकि, गंदे वाले ( async_dirty , sync_dirty , और ets ) लेनदेन शब्दार्थ को विरासत में लेते हैं अगर उन्हें लेनदेन के अंदर कहा जाता है और इस तरह ताले को पकड़ लेते हैं और दो या तीन चरण प्रतिबद्ध का उपयोग करते हैं।

उदाहरण:

add_subscriber(S) ->
    mnesia:transaction(fun() ->
       %% Transaction context 
       mnesia:read({some_tab, some_data}),
       mnesia:sync_dirty(fun() ->
           %% Still in a transaction context.
           case mnesia:read( ..) ..end), end).
add_subscriber2(S) ->
    mnesia:sync_dirty(fun() ->
       %% In dirty context 
       mnesia:read({some_tab, some_data}),
       mnesia:transaction(fun() ->
           %% In a transaction context.
           case mnesia:read( ..) ..end), end).

5.7 पैटर्न मिलान

जब फंक्शन mnesia:read/3 उपयोग नहीं किया जा सकता है, Mnesia प्रोग्रामर को एक पैटर्न के खिलाफ रिकॉर्ड मिलान के लिए कई फ़ंक्शन प्रदान करता है। सबसे उपयोगी निम्नलिखित हैं:

mnesia:select(Tab, MatchSpecification, LockKind) ->
    transaction abort | [ObjectList]
mnesia:select(Tab, MatchSpecification, NObjects, Lock) ->  
    transaction abort | {[Object],Continuation} | '$end_of_table'
mnesia:select(Cont) ->
    transaction abort | {[Object],Continuation} | '$end_of_table'
mnesia:match_object(Tab, Pattern, LockKind) ->
    transaction abort | RecordList

ये कार्य सारणी Tab सभी रिकॉर्डों के विरुद्ध एक Pattern मेल खाते हैं एक mnesia:select/2 कॉल का mnesia:select/2 करें, Pattern निम्नलिखित में वर्णित MatchSpecification का एक हिस्सा है। यह आवश्यक नहीं है कि संपूर्ण तालिका की संपूर्ण खोज के रूप में किया जाए। पैटर्न की कुंजी में अनुक्रमित और बाध्य मानों का उपयोग करके, फ़ंक्शन द्वारा किए गए वास्तविक कार्य को कुछ हैश लुकअप में संघनित किया जा सकता है। यदि ordered_set आंशिक रूप से बंधे हैं, तो ordered_set टेबल का उपयोग करके खोज स्थान को कम कर सकते हैं।

फ़ंक्शन को प्रदान किया गया पैटर्न एक मान्य रिकॉर्ड होना चाहिए, और प्रदान किए गए टपल का पहला तत्व record_name तालिका का होना चाहिए । विशेष तत्व '_' एरलंग में किसी भी डेटा संरचना से मेल खाता है (जिसे एरलंग शब्द के रूप में भी जाना जाता है)। विशेष तत्व '$<number>' Erlang चर के रूप में व्यवहार करते हैं, अर्थात, वे कुछ भी मेल खाते हैं, पहली घटना को बांधते हैं, और बाध्य चर के खिलाफ उस चर की आने वाली घटनाओं से मेल खाते हैं।

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

उदाहरण:

Wildpattern = mnesia:table_info(employee, wild_pattern), 
%% Or use
Wildpattern = #employee{_ = '_'},

कर्मचारी तालिका के लिए, जंगली पैटर्न निम्नानुसार दिखता है:

{employee, '_', '_', '_', '_', '_',' _'}.

मैच में बाधा डालने के लिए, कुछ '_' तत्वों को बदलने की आवश्यकता है । सभी महिला कर्मचारियों को बाहर देखने के लिए कोड निम्नानुसार है:

Pat = #employee{sex = female, _ = '_'},
F = fun() -> mnesia:match_object(Pat) end,
Females = mnesia:transaction(F).

मैच फ़ंक्शन का उपयोग विभिन्न विशेषताओं की समानता की जांच के लिए भी किया जा सकता है। उदाहरण के लिए, सभी कर्मचारियों को उनके रूम नंबर के बराबर कर्मचारी संख्या खोजने के लिए:

Pat = #employee{emp_no = '$1', room_no = '$1', _ = '_'},
F = fun() -> mnesia:match_object(Pat) end,
Odd = mnesia:transaction(F).

फ़ंक्शन में mnesia:match_object/2 कुछ महत्वपूर्ण विशेषताओं का अभाव mnesia:select/2 है। उदाहरण के लिए, mnesia:match_object/3 केवल मिलान रिकॉर्ड वापस कर सकते हैं, और यह समानता के अलावा अन्य बाधाओं को व्यक्त नहीं कर सकता है। दूसरी मंजिल पर पुरुष कर्मचारियों के नाम खोजने के लिए:

MatchHead = #employee{name='$1', sex=male, room_no={'$2', '_'}, _='_'},
Guard = [{'>=', '$2', 220},{'<', '$2', 230}],
Result = '$1',
mnesia:select(employee,[{MatchHead, Guard, [Result]}])

फ़ंक्शन select का उपयोग अधिक बाधाओं को जोड़ने और आउटपुट बनाने के लिए किया जा सकता है जो कि नहीं किया जा सकता है mnesia:match_object/3

दूसरा तर्क select ए है MatchSpecification । ए MatchSpecification , एस की एक सूची है MatchFunction , जहां प्रत्येक MatchFunction में एक टपल होता है {MatchHead, MatchCondition, MatchBody} :

  • MatchHead जैसा कि mnesia:match_object/3 पहले बताया गया है, वैसा ही पैटर्न है ।
  • MatchCondition प्रत्येक रिकॉर्ड पर लागू अतिरिक्त बाधाओं की एक सूची है।
  • MatchBody वापसी मूल्यों का निर्माण करता है।

मैच विनिर्देशों के बारे में जानकारी के लिए, ERTS उपयोगकर्ता गाइड में "मैच विनिर्देशों एर्लांग में" देखें । अधिक जानकारी के लिए, में ets और dets मैन्युअल पृष्ठ देखें STDLIB

कार्यों select/4 और mnesia:select/2 सीमित संख्या में परिणाम प्राप्त करने के लिए उपयोग किया Continuation जाता है , जहां परिणामों का अगला हिस्सा मिलता है। केवल सिफारिश के रूप में Mnesia उपयोग करता है NObjects । इस प्रकार, NObjects परिणाम सूची में निर्दिष्ट से अधिक या कम परिणाम लौटाए जा सकते हैं, यहां तक ​​कि खाली सूची भी वापस की जा सकती है, यदि संग्रह करने के लिए अधिक परिणाम हों।

चेतावनी

एक mnesia:select/[1|2|3|4] ही लेनदेन में उस तालिका पर किसी भी संशोधित ऑपरेशन के बाद उपयोग करने में एक गंभीर प्रदर्शन जुर्माना है । यही है, एक ही लेन-देन में उपयोग करने mnesia:write/1 से mnesia:delete/1 पहले या उससे बचें mnesia:select

यदि मुख्य विशेषता एक पैटर्न में बंधी है, तो मैच ऑपरेशन कुशल है। हालाँकि, यदि किसी पैटर्न में मुख्य विशेषता के रूप में दिया गया है , '_' या '$1' पूरी employee तालिका को उस मैच के रिकॉर्ड के लिए खोजा जाना चाहिए। इसलिए यदि तालिका बड़ी है, तो यह समय लेने वाली कार्रवाई बन सकती है, लेकिन Indexing यदि फ़ंक्शन mnesia:match_object/1 का उपयोग किया जाता है , तो इसे अनुक्रमित (देखें ) के साथ फिर से बनाया जा सकता है ।

QLC क्वेरीज़ का उपयोग Mnesia तालिकाओं को खोजने के लिए भी किया जा सकता है । mnesia:table/[1|2] क्यूएलसी क्वेरी के अंदर जनरेटर के रूप में फ़ंक्शन का उपयोग करके , आप क्वेरी को एक Mnesia टेबल पर संचालित करते हैं । Mnesia विशिष्ट विकल्प के लिए mnesia:table/2 कर रहे हैं {lock, Lock} , {n_objects,Integer} और {traverse, SelMethod} :

  • lock निर्दिष्ट करता Mnesia है कि क्या तालिका पर एक रीड या राइट लॉक प्राप्त करना है।
  • n_objects निर्दिष्ट करता है कि QLC में प्रत्येक परिणाम में कितने परिणाम वापस करने हैं।
  • traverse निर्दिष्ट करता Mnesia है कि तालिका को पार करने के लिए किस फ़ंक्शन का उपयोग करना है। डिफ़ॉल्ट select का उपयोग किया जाता है, लेकिन उपयोगकर्ता के {traverse, {select, MatchSpecification}} लिए एक विकल्प के रूप में उपयोग करके mnesia:table/[1|2] तालिका के अपने दृष्टिकोण को निर्दिष्ट कर सकते हैं।

यदि कोई विकल्प निर्दिष्ट नहीं किया जाता है, तो एक रीड लॉक का अधिग्रहण select किया जाता है , प्रत्येक चंक में 100 परिणाम वापस किए जाते हैं, और इसका उपयोग तालिका को पार करने के लिए किया जाता है:

mnesia:table(Tab) ->
    mnesia:table(Tab, [{n_objects,100},{lock, read}, {traverse, select}]).

फ़ंक्शन mnesia:all_keys/1 एक तालिका में सभी कुंजी देता है।

५.ter इतरपन

Mnesia निम्न कार्य प्रदान करता है जो एक तालिका में सभी अभिलेखों पर पुनरावृति करता है:

mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort
mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort
mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort
mnesia:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort

ये फ़ंक्शन Mnesia तालिका पर पुनरावृति करते हैं Tab और फ़ंक्शन Fun को प्रत्येक रिकॉर्ड पर लागू करते हैं । Fun दो तर्क लेता है, पहला तालिका से एक रिकॉर्ड है, और दूसरा संचायक है। Fun एक नया संचायक देता है।

पहली बार Fun लागू किया गया Acc0 है, दूसरा तर्क है। अगली बार Fun कहा जाता है, पिछली कॉल से वापसी मान का उपयोग दूसरे तर्क के रूप में किया जाता है। Fun रिटर्न के लिए अंतिम कॉल शब्द , फ़ंक्शन का रिटर्न मूल्य mnesia:foldl/3 या है mnesia:foldr/3

इन कार्यों के बीच का अंतर वह क्रम है जिससे तालिका ordered_set तालिकाओं के लिए एक्सेस की जाती है । अन्य तालिका प्रकारों के लिए फ़ंक्शन समान हैं।

LockType निर्दिष्ट करता है कि पुनरावृत्ति के लिए किस प्रकार का ताला प्राप्त किया जाना है, डिफ़ॉल्ट है read । यदि रिकॉर्ड को पुनरावृति के दौरान लिखा या हटाया जाता है, तो एक राइट लॉक अधिग्रहित किया जाना है।

इन फ़ंक्शन का उपयोग किसी तालिका में रिकॉर्ड खोजने के लिए किया जा सकता है जब फ़ंक्शन के लिए बाधाओं को लिखना असंभव है mnesia:match_object/2 , या जब आप कुछ रिकॉर्ड पर कुछ कार्रवाई करना चाहते हैं।

उदाहरण के लिए, 10 से कम वेतन पाने वाले सभी कर्मचारियों को निम्न प्रकार से देख सकते हैं:

find_low_salaries() ->
  Constraint = 
       fun(Emp, Acc) when Emp#employee.salary < 10 ->
              [Emp | Acc];
          (_, Acc) ->
              Acc
       end,
  Find = fun() -> mnesia:foldl(Constraint, [], employee) end,
  mnesia:transaction(Find).

10 से कम वेतन वाले सभी के लिए वेतन बढ़ाने के लिए और सभी राशि के योग को वापस करने के लिए:

increase_low_salaries() ->
   Increase = 
       fun(Emp, Acc) when Emp#employee.salary < 10 ->
              OldS = Emp#employee.salary,
              ok = mnesia:write(Emp#employee{salary = 10}),
              Acc + 10 - OldS;
          (_, Acc) ->
              Acc
       end,
  IncLow = fun() -> mnesia:foldl(Increase, 0, employee, write) end,
  mnesia:transaction(IncLow).

कई अच्छी चीजें इट्रेटर फ़ंक्शंस के साथ की जा सकती हैं लेकिन बड़ी तालिकाओं के लिए प्रदर्शन और मेमोरी उपयोग के बारे में कुछ सावधानी बरतें।

इन पुनरावृत्तियों को नोड्स पर कॉल करें जिसमें तालिका की प्रतिकृति है। फ़ंक्शन की प्रत्येक कॉल Fun तालिका तक पहुंचती है और यदि तालिका किसी अन्य नोड पर रहती है तो यह बहुत अनावश्यक नेटवर्क ट्रैफ़िक उत्पन्न करती है।

Mnesia कुछ फ़ंक्शन भी प्रदान करता है जो उपयोगकर्ता के लिए तालिका पर पुनरावृति करना संभव बनाता है। यदि तालिका प्रकार की नहीं है, तो पुनरावृत्ति का क्रम अनिर्दिष्ट है ordered_set :

mnesia:first(Tab) ->  Key | transaction abort
mnesia:last(Tab)  ->  Key | transaction abort
mnesia:next(Tab,Key)  ->  Key | transaction abort
mnesia:prev(Tab,Key)  ->  Key | transaction abort
mnesia:snmp_get_next_index(Tab,Index) -> {ok, NextIndex} | endOfTable

first / last और next / prev का आदेश केवल ordered_set तालिकाओं के लिए मान्य है , वे अन्य तालिकाओं के लिए समानार्थक शब्द हैं। जब तालिका का अंत पहुँच जाता है, तो विशेष कुंजी '$end_of_table' वापस आ जाती है।

यदि ट्रैवर्सल के दौरान रिकॉर्ड लिखे और हटाए गए हैं, तो फ़ंक्शन का उपयोग करें mnesia:foldl/3 या लॉक के mnesia:foldr/3 साथ write । या फ़ंक्शन mnesia:write_lock_table(Tab) का उपयोग करते समय first और next

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

गंदा संदर्भ में, जो है, sync_dirty या async_dirty , संशोधित रिकॉर्ड स्थानीय प्रतिलिपि में संग्रहीत नहीं हैं; इसके बजाय, प्रत्येक रिकॉर्ड को अलग से अपडेट किया जाता है। यह बहुत नेटवर्क ट्रैफ़िक उत्पन्न करता है यदि तालिका में दूसरे नोड पर प्रतिकृति है और अन्य सभी कमियां हैं जो गंदे संचालन हैं। विशेष रूप से आदेशों के लिए mnesia:first/1 और mnesia:next/2 , पहले के रूप में वर्णित mnesia:dirty_first(Tab) और mnesia:dirty_next/2 लागू होने वाली कमियां , यानी, तालिका के लिए कोई लेखन पुनरावृत्ति के दौरान नहीं किया जाना है।

Original text