ما هي الطريقة "الأفضل" لإجراء المعاملات الموزعة عبر قواعد بيانات متعددة باستخدام Spring وHibernate

StackOverflow https://stackoverflow.com/questions/128377

سؤال

لدي تطبيق - يشبه إلى حد كبير أداة مساعدة - موجود في الزاوية ويقوم بتحديث قاعدتي بيانات مختلفتين بشكل دوري.

إنه تطبيق مستقل صغير تم إنشاؤه باستخدام سياق تطبيق Spring.يحتوي السياق على اثنين من معامل Hibernate Session التي تم تكوينها فيه، والتي بدورها تستخدم مصادر بيانات Commons DBCP التي تم تكوينها في Spring.

حاليا لا توجد إدارة للمعاملات، ولكن أود أن أضيف بعض.يعتمد التحديث إلى قاعدة بيانات واحدة على نجاح التحديث إلى الأخرى.

لا يوجد التطبيق في حاوية Java EE - بل يتم تشغيله بواسطة فئة مشغل ثابتة يتم استدعاؤها من برنامج نصي shell.تقوم فئة المشغل بإنشاء مثيل لسياق التطبيق ثم تستدعي طريقة على إحدى وحداتها.

ما هي الطريقة "الأفضل" لوضع المعاملات حول تحديثات قاعدة البيانات؟

سأترك تعريف "الأفضل" لك، ولكن أعتقد أنه يجب أن يكون عبارة عن وظيفة "سهلة الإعداد"، و"سهلة التكوين"، و"غير مكلفة"، و"سهلة التعبئة وإعادة التوزيع".وبطبيعة الحال فإن البرمجيات الحرة والمفتوحة المصدر ستكون جيدة.

هل كانت مفيدة؟

المحلول

أفضل طريقة لتوزيع المعاملات على أكثر من قاعدة بيانات هي:لا.

سيوجهك بعض الأشخاص إلى XA لكن XA (أو الالتزام على مرحلتين) هو كذبة (أو سوق).

يتصور:بعد أن أبلغت المرحلة الأولى مدير XA بأنه يمكنه إرسال الالتزام النهائي، يفشل اتصال الشبكة بإحدى قواعد البيانات.ماذا الآن؟نفذ الوقت؟سيؤدي ذلك إلى ترك قاعدة البيانات الأخرى تالفة.التراجع؟مشكلتين:لا يمكنك التراجع عن الالتزام وكيف تعرف ما حدث لقاعدة البيانات الثانية؟ربما فشل اتصال الشبكة بعد أن نجح في إرسال البيانات وتم فقدان رسالة "النجاح" فقط؟

أفضل طريقة هي نسخ البيانات في مكان واحد.استخدم نظامًا يسمح لك بإلغاء النسخة ومتابعتها في أي وقت (على سبيل المثال، تجاهل البيانات الموجودة لديك بالفعل أو اطلب التحديد حسب المعرف واطلب السجلات فقط > الحد الأقصى (المعرف) لنسختك).حماية هذا مع الصفقة.هذه ليست مشكلة لأنك تقرأ البيانات من المصدر فقط، لذلك عندما تفشل المعاملة لأي سبب من الأسباب، يمكنك تجاهل قاعدة البيانات المصدر.لذلك، هذه معاملة قديمة أحادية المصدر.

بعد قيامك بنسخ البيانات، قم بمعالجتها محليًا.

نصائح أخرى

قم بإعداد مدير المعاملات في السياق الخاص بك.تحتوي مستندات الربيع على أمثلة، وهي بسيطة جدًا.ثم عندما تريد تنفيذ معاملة:

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

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

لمزيد من الأمثلة والمعلومات ربما انظر إلى هذا:معاملات XA باستخدام Spring

عندما تقول "قاعدتي بيانات مختلفتين"، هل تقصد خوادم قاعدة بيانات مختلفة، أو مخططين مختلفين داخل نفس خادم قاعدة البيانات؟

إذا كان الأول، فإذا كنت تريد معاملات كاملة، فأنت بحاجة إلى واجهة برمجة تطبيقات معاملات XA، والتي توفر التزامًا كاملاً على مرحلتين.ولكن الأهم من ذلك، أنك تحتاج أيضًا إلى منسق/مراقب للمعاملات يدير نشر المعاملات بين أنظمة قواعد البيانات المختلفة.هذا جزء من مواصفات JavaEE، وهو جزء نادر جدًا منه.يعد منسق TX نفسه عبارة عن برنامج معقد.يتحدث البرنامج التطبيقي الخاص بك (عبر Spring، إذا كنت ترغب في ذلك) إلى المنسق.

ومع ذلك، إذا كنت تقصد فقط قاعدتي بيانات داخل نفس خادم قاعدة البيانات، فيجب أن تعمل معاملات JDBC الفانيليا بشكل جيد، فقط قم بإجراء عملياتك على قاعدتي البيانات ضمن معاملة واحدة.

في هذه الحالة، ستحتاج إلى مراقبة المعاملات (خادم يدعم بروتوكول XA) وتأكد من أن قواعد البيانات الخاصة بك تدعم بروتوكول XA أيضًا.معظم (جميع؟) خوادم J2EE تأتي مع مراقبة المعاملات المضمنة.إذا لم يتم تشغيل التعليمات البرمجية الخاصة بك في خادم J2EE، فهناك مجموعة من البدائل المستقلة - Atomicos، وBitronix، وما إلى ذلك.

يمكنك تجربة Spring ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html الذي يدعم معاملة قاعدة البيانات الموزعة.قد يكون هذا بديلاً أفضل لـ XA

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top