2008-09-24 12 views
25

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

यह एक छोटा सा स्टैंडअलोन ऐप है जिसे स्प्रिंग एप्लिकेशन संदर्भ के साथ बनाया गया है। इस संदर्भ में स्प्रिंग में कॉन्फ़िगर किए गए कॉमन्स डीबीसीपी डेटा स्रोतों का उपयोग करके कॉन्फ़िगर किए गए दो हाइबरनेट सत्र कारखानों में कॉन्फ़िगर किया गया है।

वर्तमान में कोई लेनदेन प्रबंधन नहीं है, लेकिन मैं कुछ जोड़ना चाहता हूं। एक डेटाबेस में अद्यतन दूसरे के लिए एक सफल अद्यतन पर निर्भर करता है।

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

डेटाबेस अपडेट के आसपास लेनदेन को रखने का सबसे अच्छा तरीका क्या है?

मैं आपको 'सर्वश्रेष्ठ' की परिभाषा छोड़ दूंगा, लेकिन मुझे लगता है कि यह 'आसान सेट अप', 'कॉन्फ़िगर करने में आसान', 'सस्ता', और 'पैकेज करने में आसान और पुनर्वितरण' के कुछ कार्य होना चाहिए। । स्वाभाविक रूप से एफओएसएस अच्छा होगा।

उत्तर

26

लेनदेन वितरित करने का सबसे अच्छा तरीका एक डेटाबेस है: मत करो।

कुछ लोग आपको एक्सए पर इंगित करेंगे लेकिन एक्सए (या दो चरण कमिट) एक झूठ (या मार्केटिज) है।

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

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

डेटा कॉपी करने के बाद, इसे स्थानीय रूप से संसाधित करें।

+5

वितरित लेनदेन को सभी 4 एसीआईडी ​​गुणों को संतुष्ट करना होगा। तुम्हारी समस्या क्या है? आपके द्वारा वर्णित परिदृश्य ऐसा नहीं हो सकता है, क्योंकि प्रबंधक एक दूसरे के साथ संवाद कर रहे हैं और केवल तभी प्रतिबद्ध होते हैं जब सभी भाग लेने वाले नोड्स ने "जाओ" का आदान-प्रदान किया हो। – Falcon

+6

@ फाल्कन: तो क्या होता है यदि नेटवर्क तैयार और COMMIT के बीच विफल रहता है? या सर्वर में से एक मर जाता है? "ऐसा नहीं हो सकता" वास्तविकता में नहीं हो सकता है। –

+2

नहीं, उन्हें वापस रोल करने का निर्देश नहीं दिया गया है क्योंकि इस परिदृश्य में, कुछ नोड्स पहले से ही प्रतिबद्ध हैं। क्या होता है जब दुर्घटनाग्रस्त नोड उपलब्ध हो जाता है, लेनदेन समन्वयक इसे फिर से करने के लिए कहता है। क्योंकि नोड ने "तैयार" चरण में सकारात्मक प्रतिक्रिया दी, इसलिए इसे "प्रतिबद्ध" करने में सक्षम होना आवश्यक है, भले ही यह किसी दुर्घटना से वापस आ जाए। –

6

अपने संदर्भ में एक लेनदेन प्रबंधक सेटअप करें। वसंत दस्तावेज़ों में उदाहरण हैं, और यह बहुत आसान है। फिर जब आप एक सौदे पर अमल करना चाहते हैं:

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager); 

    tt.execute(new TransactionCallbackWithoutResult(){ 
    protected void doInTransactionWithoutResult(
      TransactionStatus status) { 
     updateDb1(); 
     updateDb2(); 
    } 
} catch (TransactionException ex) { 
    // handle 
} 

अधिक उदाहरण के लिए, और जानकारी शायद इसे देखो: XA transactions using Spring

+3

का एक बेहतर विकल्प हो सकता है यह उदाहरण वास्तव में प्रश्न का उत्तर नहीं देता है या यह गलत तरीके से इसका उत्तर भी देता है: ओपी ने उल्लेख किया कि उसके पास दो हाइबरनेट सत्र कारखानों को कॉन्फ़िगर किया गया है जिसके लिए दो अलग-अलग लेनदेन प्रबंधकों की आवश्यकता होगी। उत्तर में उदाहरण केवल एक लेनदेन प्रबंधक का उपयोग करता है जिसे किसी भी करीबी निर्दिष्ट नहीं किया जाता है। परिणामस्वरूप एक ही हाइबरनेट लेनदेन प्रबंधक का उपयोग त्रुटियों पर दो डीबी में से किसी एक को रोलबैक नहीं करेगा। उदाहरण के लिए एक 'चेनट्रांसक्शन प्रबंधक' (जैसा कि @ पान धक्षनमुर्ती द्वारा नोट किया गया है) का उपयोग करने में मदद मिल सकती है लेकिन इसका उत्तर इस उत्तर में नहीं दिया गया है। – Chriki

5

जब आप कहते हैं कि "दो अलग-अलग डेटाबेस", आप विभिन्न डेटाबेस सर्वर मतलब है, या एक ही डीबी सर्वर के भीतर दो अलग-अलग स्कीमा?

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

यदि, हालांकि, आप एक ही डीबी सर्वर के भीतर दो डेटाबेस का मतलब है, तो वेनिला जेडीबीसी लेनदेन को ठीक काम करना चाहिए, केवल एक ही लेनदेन के भीतर दोनों डेटाबेस के खिलाफ अपने परिचालन करें।

3

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

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