استعادة تحميل من SQL Server إلى Oracle بعد انقطاع VPN
يترك انقطاع VPN المستدعي غير متأكد مما إذا كانت عملية الالتزام في Oracle قد تمت. ومعرّف دفعة دائم يجعل أسئلة الاستخراج والتطبيق والمطابقة قابلة للإجابة عنها واحدة تلو الأخرى.
تموت عملية نقل بين قواعد البيانات عندما ينقطع VPN، و«أعد تشغيلها» ليس خطة استرداد. قد يكون استخراج المصدر مكتملاً، وقد يكون الهدف قد التزم بالفعل، أو ربما ضاع الرد ببساطة في طريق العودة. تحتاج هذه الحالات الثلاث إلى إجراءات مختلفة، والعميل الذي لا يعرف سوى «خطأ» لا يستطيع التمييز بينها.
الإصلاح معماري: امنح كل عملية تشغيل هوية دفعة دائمة، ودع قواعد البيانات تجيب عن الأسئلة بدلاً من أن يخمّن العميل.
ما الذي تضمنه قاعدة البيانات فعلاً
يوفر SQL Server وOracle كلاهما الذرية داخل المعاملة. ولا يوفّر أي منهما ذرية عبر الاثنين معاً. لا يؤدي الاتصال المفقود إلى إفساد قاعدة البيانات، ولا يفرض تراجعاً يدوياً أيضاً، لأن الخادم يحسم معاملته بنفسه دونك. ما ينكسر هو معرفة المستدعي بالنتيجة.
الالتزام بشكل منفصل يعني الالتزام بشكل منفصل. ولا يدمج VPN الذي يحمل الاتصالين التزامين في وحدة عمل واحدة.
الالتزام الذي لم تسمع به أبداً
هناك نمط فشل واحد يعاقب منطق إعادة المحاولة الساذج: يلتزم الخادم، ولا يصل الإقرار إلى المستدعي أبداً. توثّق Oracle ذلك كمشكلة النتيجة غير المعروفة وتوفّر Transaction Guard لها في توثيق المعاملات. خطأ الاتصال ليس دليلاً على فشل التزام مُرسل، والتعامل معه كدليل هو الطريقة التي تُنشر بها الدفعة مرتين. ويكون هذا التمييز أهم ما يكون في مسار إعادة المحاولة، حيث يملك المشغّل رسالة خطأ ولا يملك أي إشارة أخرى يتصرف بناءً عليها.
لذلك يجب أن تقرأ خطوة الاسترداد النتيجة من الهدف بدلاً من استنتاجها من نص الخطأ.
امنح النقل هوية دفعة
تحصل كل عملية تشغيل على معرّف دفعة ثابت، ويسجّل الهدف ما فعله بذلك المعرّف. تتكون دورة الحياة من أربع خطوات، وهي تبدو نفسها بغض النظر عن البائع:
- الاستخراج: دفعة مصدر محدّدة وثابتة بمخطط وحدود مسجّلين.
- النقل إلى منطقة التجهيز لدى الهدف، واكتشاف المحتوى الناقص أو المتعارض قبل إعلانه جاهزاً.
- التطبيق وفق قواعد التفرد أو القفل الخاصة بالهدف، وتسجيل الإكمال في المعاملة المحلية نفسها.
- المطابقة للنتيجة الدائمة عبر البروتوكول المدعوم قبل الإقرار أو إعادة المحاولة.
تعيد المحاولات استخدام المعرّف نفسه. فمعرّف جديد لكل محاولة يبطل منع التكرار الذي بنيته للتو، وهو ما يبدو بديهياً حتى يولّد غلاف إعادة المحاولة واحداً تلقائياً.
كما يمنحك المعرّف شيئاً تطابقه لاحقاً، بعد وقت طويل من زوال عملية العميل.
احجز الدفعة، ثم طبّق
يجب أن تحجز خطوة التطبيق معرّف الدفعة، وتُجري تغييرات الأعمال، وتسجّل الإكمال في معاملة محلية واحدة. إن فعلت الفحص والإدراج كعبارتين منفصلتين، فستعيد إدخال حالة التسابق التي كنت تحاول إزالتها. وإذا تسابق عاملان، يفوز حجز واحد بالضبط ويُبلّغ الآخر بذلك.
عدم وجود سجل إكمال ليس دليلاً على أن معاملة جارية لن تلتزم أبداً. يجب أن يحوّل الحجز المحاولات المتنافسة إلى تسلسل، أو يجب أن يقرأ البروتوكول النتيجة الدائمة قبل اتخاذ أي قرار.
استخدم آلية قاعدة البيانات المدعومة لذلك التسلسل بدلاً من حلقة افحص-ثم-أعد في كود التطبيق.
ما لا يزال التصميم عاجزاً عن وعده
يجعل التجهيز العمل قابلاً لإعادة التشغيل ويقلل الاعتماد على جلسة واحدة طويلة الأجل. لكنه لا ينشئ التزاماً ذرياً واحداً عبر SQL Server وOracle وأي أثر جانبي خارجي ينفذه العمل. وإذا كان العمل يحتاج ذلك حقاً، فصمّم معاملة موزعة مدعومة أو عملية مطابقة وتحقّق من صلاحيتها، بما في ذلك من يملك العمل المعلّق. وأي شيء أضعف من ذلك مكانه دليل تشغيل المطابقة، لا كود النقل.
اقبل الانقطاع في ثلاثة مواضع: أثناء النقل، وأثناء التطبيق، وبعد الالتزام لكن قبل الإقرار. ثم افحص نتيجة العمل لا رسالة العميل، ودع سجل الدفعة يقول ما إذا كان العمل ناقصاً أو ملتزماً أو ما زال غير محسوم.