التنفيذ المتين مقابل نمط الملحمة لسير عمل المدفوعات
تعويضات الملحمة ضرورية لكنها غير كافية. يوفر التنفيذ المتين ضمانات التنفيذ مرة واحدة بالضبط التي تتطلبها العمليات المالية.
التنفيذ المتين مقابل نمط الملحمة: اختيار نموذج سير العمل المناسب للمدفوعات
الخطوة 3 من 5 تفشل. مستهلك الطابور يتعطل. عند إعادة التشغيل، هل يعيد التشغيل من الخطوة 1؟ يتخطى إلى الخطوة 4؟ الإجابة تعتمد على حالة لا يتتبعها الطابور.
هذه هي المشكلة المركزية للعمليات المالية متعددة الخطوات. فتح الحساب يتطلب أربع خطوات منسقة: إنشاء كيان، توفير حسابات دفتر الحسابات، تعيين IBAN، تشغيل التحقق من KYC. تنفيذ المدفوعات يتطلب خمسًا: التحقق، الفحص، الخصم، الإرسال إلى المقاصة، تتبع التسوية. كل خطوة تعتمد على السابقة. كل خطوة لها آثار جانبية لا يمكن تكرارها بشكل عرضي.
نمطان معماريان يعالجان هذه المشكلة. يحلانها بشكل مختلف، بمقايضات مختلفة، والاختيار يهم أكثر من معظم قرارات البنية في نظام مدفوعات.
نمط الملحمة
تنسق الملاحم خدمات مستقلة من خلال معاملات تعويضية. يوجد متغيران.
الكوريغرافيا: كل خدمة تنشر أحداثًا. الخدمة التالية تشترك وتتصرف. عندما يفشل شيء، تنشر الخدمة الفاشلة حدث تعويض، وتستمع الخدمات السابقة وتتراجع عن عملها.
الجاذبية هي فك الارتباط. لا منسق مركزي. كل خدمة تملك منطقها. أضف خطوة جديدة بإضافة مشترك جديد.
المشكلة هي الرؤية. "العملية" لا توجد في أي مكان كقطعة واحدة. إنها خاصية ناشئة لتدفقات الأحداث عبر الخدمات. تصحيح أخطاء دفعة فاشلة يتطلب ربط السجلات عبر كل مستهلك شارك. إذا فُقد حدث (والأحداث تُفقد، تقسيمات الشبكة، تعطل المستهلك قبل الإقرار، فيضان طابور الرسائل الميتة)، الفشل صامت. لا مكون يعرف أن العملية غير مكتملة، لأن لا مكون يتتبع العملية.
التنسيق: منسق مركزي يرسل أوامر لكل خدمة بالتسلسل. المنسق يعرف الخطوة الحالية. إذا فشلت خطوة، ينفذ المنسق التعويض بترتيب عكسي.
هذا أفضل. العملية مرئية في مكان واحد. يمكن للمشغل فحص حالة المنسق ورؤية: الخطوة 3 من 5 معلقة. المنسق هو المصدر الوحيد للحقيقة للعملية.
لكن: المنسق نفسه يجب أن يصمد أمام الأعطال. إذا تعطل المنسق بين الخطوة 3 (خصم الحساب) والخطوة 4 (الإرسال إلى المقاصة)، ماذا يحدث؟ الإجابة تعتمد على كيفية حفظ المنسق لحالته. إذا استخدم آلة حالة في الذاكرة، تُفقد الحالة. إذا حفظ في قاعدة بيانات، يعتمد التعافي على ما إذا كانت كتابة قاعدة البيانات التزمت قبل التعطل. موثوقية المنسق نفسه تصبح مشكلة تصميم، مشكلة لا يحلها تنسيق الملحمة بطبيعته.
كلا متغيري الملحمة يتشاركان خاصية أساسية: كل خطوة هي معاملة مستقلة. الملحمة تنسقها. لكن التنسيق نفسه ليس معاملاتيًا. الفجوة بين "الخطوة 3 التزمت" و"المنسق سجل أن الخطوة 3 التزمت" هي حيث يختبئ فقدان البيانات.
التنفيذ المتين
التنفيذ المتين يتخذ نهجًا مختلفًا. محرك سير العمل يسجل كل خطوة قبل تنفيذها. السجل هو حالة العملية. إذا تعطل المحرك وأعيد تشغيله، يعيد تشغيل السجل ويستأنف عند نقطة الانقطاع بالضبط.
النموذج الذهني مختلف عن الملاحم. في الملحمة، تحدد المسار الأمامي ومسار التعويض كاهتمامات منفصلة. في التنفيذ المتين، تكتب سير العمل كدالة خطية، الخطوة 1، الخطوة 2، الخطوة 3، والمحرك يضمن أن الدالة تكتمل. إذا فشلت خطوة بشكل دائم (ليس خطأ عابرًا، بل فشل أعمال حقيقي، "الحساب غير موجود")، ينفذ المحرك التعويض كجزء من نفس سير العمل المُسجَّل.
ثلاث خصائص تميز التنفيذ المتين عن تنسيق الملحمة:
السجل يصمد أمام إعادة تشغيل العمليات. يكتب المحرك كل خطوة في سجل متين قبل التنفيذ. عند إعادة التشغيل، يعيد تشغيل السجل ويستأنف. السجل ليس تحسينًا أو فكرة لاحقة، إنه آلية التنفيذ. العملية لا تعمل "فوق" السجل. العملية هي السجل، مُعاد تشغيله.
التكرار المنع مضمون بالمحرك. في الملحمة، كل خدمة يجب أن تنفذ التكرار المنع بشكل مستقل. إذا أعاد المنسق محاولة الخطوة 3، يجب على الخدمة اكتشاف التكرار وإرجاع النتيجة السابقة. في التنفيذ المتين، يتتبع المحرك الخطوات المكتملة. عند إعادة التشغيل، الخطوات المكتملة ترجع نتائجها المخزنة مؤقتًا دون إعادة التنفيذ. الخدمة لا تحتاج أن تكون مانعة للتكرار، المحرك يضمن استدعاءها مرة واحدة على الأكثر لكل مثيل سير عمل.
السجل هو مسار التدقيق. لكل سير عمل معرف ارتباط. كل خطوة مسجلة بالمدخلات والمخرجات والمدة والنتيجة. يمكن للمدقق إعادة بناء دورة الحياة الكاملة لدفعة من معرف واحد. ليست ميزة تسجيل، بل خاصية هيكلية لنموذج التنفيذ. مسار التدقيق موجود لأن السجل موجود، والسجل موجود لأن المحرك لا يمكنه العمل بدونه.
مثال عملي: تحويل SEPA الائتماني
تتبع دفعة مع كلا النمطين.
المسار السعيد (كلا النمطين يتعاملان معه بشكل متطابق):
- التحقق من IBAN والمبلغ ✓
- فحص مكافحة غسل الأموال (مزود خارجي) ✓
- خصم حساب المرسل (دفتر الحسابات) ✓
- الإرسال إلى المقاصة (SEPA SCT عبر CSM) ✓
- تتبع حالة التسوية ✓
الفشل: الخطوة 4 مرفوضة من شبكة المقاصة.
حساب المرسل تم خصمه (الخطوة 3). شبكة المقاصة رفضت الإرسال (الخطوة 4). يجب عكس الخصم.
نهج الملحمة:
محول المقاصة ينشر حدث PaymentRejected. مستهلك تعويض يلتقطه، يستدعي دفتر الحسابات لعكس الخصم، وينشر DebitReversed. سجل الدفع الأصلي يُحدَّث إلى FAILED.
لكن: ماذا لو تعطل مستهلك التعويض قبل عكس الخصم؟ حدث PaymentRejected يجلس في طابور الرسائل الميتة. حساب المرسل يبقى مخصومًا. لا مكون يتتبع هذه الحالة بنشاط. الاكتشاف يعتمد إما على تشغيل مطابقة (بعد ساعات أو أيام) أو شكوى عميل.
التخفيف موجود: طوابير مستمرة بتسليم مرة واحدة على الأقل، مراقبة صحة المستهلك، تنبيه طابور الرسائل الميتة. كل تخفيف هو نظام إضافي للبناء والصيانة. مسار التعويض يصبح بنفس تعقيد المسار الأمامي.
نهج التنفيذ المتين:
الخطوة 4 تفشل. المحرك يسجل الفشل في السجل. ينفذ معالج التعويض (عكس الخصم) كخطوة مُسجَّلة تالية. إذا تعطل المحرك أثناء العكس، يعيد تشغيل السجل عند إعادة التشغيل ويعيد تنفيذ العكس (وهو مانع للتكرار لأن المحرك خزّن حالة الخطوة مؤقتًا).
التسلسل الكامل، المسار الأمامي، الفشل، التعويض، في سجل واحد بمعرف ارتباط واحد. المشغل يفحص سير العمل ويرى:
Workflow: SEPA-CT-2026-02-21-00847
Step 1: Validate → OK (12ms)
Step 2: AML Screen → OK (340ms, provider: screening-svc)
Step 3: Debit → OK (0.4ms, transfer_id: 9a3f...)
Step 4: Submit Clearing → REJECTED (reason: AC03, invalid creditor account)
Step 5: Compensate Debit → OK (0.3ms, reversal_id: b7c1...)
Status: COMPENSATED
لا تحليل جنائي للسجلات. لا طابور رسائل ميتة للمراقبة. لا مطابقة مطلوبة لاكتشاف الفشل. العملية توثق نفسها.
أين يناسب كل نمط
| الجانب | الملحمة (كوريغرافيا) | الملحمة (تنسيق) | التنفيذ المتين |
|---|---|---|---|
| رؤية العملية | موزعة عبر سجلات الأحداث | منسق مركزي | سجل واحد بإعادة تشغيل كاملة |
| نموذج التعافي | أحداث تعويض (قد تُفقد) | المنسق يستأنف (إذا حُفظت الحالة) | إعادة تشغيل السجل (مضمونة) |
| مسار التدقيق | يتطلب تجميع سجلات عبر الخدمات | سجل المنسق (نقطة واحدة) | مدمج، السجل هو المسار |
| التكرار المنع | كل خدمة يجب أن تنفذه | كل خدمة يجب أن تنفذه | مضمون بالمحرك |
| الفشل الجزئي | صامت إذا فُقد حدث التعويض | غير مؤكد إذا تعطل المنسق أثناء خطوة | السجل يصمد، إعادة التشغيل تستأنف |
| التعقيد | منخفض (لكل خدمة)، عالٍ (على مستوى النظام) | متوسط (المنسق)، متوسط (الخدمات) | منخفض (كود سير العمل)، منخفض (البنية التحتية) |
| الأفضل لـ | تنسيق مرتبط بشكل فضفاض، منخفض المخاطر | تنسيق متعدد الخدمات | عمليات مالية تتطلب التنفيذ مرة واحدة بالضبط |
الملاحم ليست خاطئة. تعمل جيدًا للتنسيق الذي يتحمل الاتساق النهائي: حجوزات المخزون، سير عمل الإشعارات، خطوط أنابيب التحليلات. متغير الكوريغرافيا يتفوق عندما تكون الخدمات مستقلة حقًا و"العملية" هي راحة وليست متطلبًا.
للعمليات المالية، حيث كل خطوة لها آثار جانبية لا رجعة فيها، حيث يجب أن يكون التعويض قابلًا للإثبات، حيث سيسأل المدقق "أرني كل خطوة من هذه الدفعة"، يوفر التنفيذ المتين ضمانات أقوى بتعقيد تشغيلي أقل.
الصناعة تقاربت
الدليل عملي وليس نظريًا. صناعة المدفوعات اتخذت خيارها:
- Stripe يستخدم Temporal (تنفيذ متين) لتنسيق المدفوعات.
- Revolut يستخدم Temporal للتدفقات الحرجة للمدفوعات.
- Wise رحّل من تنسيق الملحمة نحو Temporal.
- N26 يستخدم Kafka + Sagas، ويناقش علنًا التعقيد التشغيلي لإدارة التعويض.
النمط واضح. للمسارات الحرجة للمدفوعات، الصناعة تتقارب على التنفيذ المتين. النموذج القائم على السجل يوفر التتبع الذي يتطلبه المنظمون (DORA المادة 11-12) والرؤية التشغيلية التي تحتاجها فرق الهندسة.
اقرأ المزيد: سير العمل، محرك التنفيذ المتين | المدفوعات، تنسيق المدفوعات
المصادر:
- Garcia-Molina, Hector and Salem, Kenneth. "Sagas." SIGMOD '87، ورقة نمط الملحمة الأصلية
- DORA، اللائحة (EU) 2022/2554، المادة 11-12 (تتبع تكنولوجيا المعلومات والتعافي)
- توثيق Restate: "Microservice Orchestration" (https://docs.restate.dev/tour/microservice-orchestration)
- توثيق Temporal: "What is durable execution?" (https://docs.temporal.io/concepts)