تكرار السؤال: …
الإجابة المختصرة
تحدث عند محاولة حفظ البيانات في قاعدة البيانات ونشر رسالة لـ RabbitMQ/Kafka معاً وفشل أحدهما؛ وتحلها Outbox بحفظ الرسالة في جدول محلي داخل نفس المعاملة ثم نشرها لاحقاً.
الشرح
لا يمكنك عمل Distributed Transaction موثوقة بين قاعدة بيانات و Message Broker. إذا حفظت الطلب في SQL وفشلت الشبكة قبل إرسال الرسالة، لن يعلم المستودع بالطلب. مع نمط Outbox، يتم إدراج الرسالة في جدول OutboxMessages بنفس معاملة قاعدة البيانات. يقوم عامل خلفي مستقل (أو حزمة MassTransit Outbox) بقراءة الجدول ونشر الرسائل للموزع مع ضمان تسليم 'مرة واحدة على الأقل'.
مثال بالكود
// تفعيل MassTransit Transactional Outbox
builder.Services.AddMassTransit(x => {
x.AddEntityFrameworkOutbox<AppDbContext>(o => {
o.UsePostgres();
o.UseBusOutbox();
});
});أخطاء شائعة
- إرسال رسائل الـ Message Broker مباشرة داخل دوال المتحكمات قبل التأكد من نجاح حفظ معاملة قاعدة البيانات.