محتويات الدورة

Spring Boot / المتقدم: المراقبة والإصدارات المتينة / الدرس 17

مسارات العمل الموثوقة وحد الصندوق الصادر

نسق الحالة المثبتة وهوية العملية وتسليمها المتكرر ومنع تكرار المستهلك دون ادعاء أن الحدث المحلي أثر بعيد مرة واحدة.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • فصل الذرية المحلية من التسليم البعيد.
  • شرح الهوية الدائمة وتكافؤ المحتوى.
  • استخدام الحدث تلميحاً لا سجل الاسترداد الوحيد.

حدد الآثار التي تحميها المعاملة

يمكن أن يشترك الطلب وسجل الصندوق في معاملة إذا استخدما المورد والمدير الداعمين نفسيهما. لا تتراجع رسالة أو HTTP أوعملية دفع بـ JPA عادية. قد ينشر الإرسال قبل التثبيت طلباً لم يوجد، وقد تضيع نية ذاكرية بعد التثبيت بانهيار.

يحفظ الصندوق نية التسليم مع العمل ثم يقرأها عامل ويعالجها بحدود ويسجل التقدم. قد يفقد التأكيد بعد التسليم فيتكرر، فيحتاج المستهلك منعاً دائماً أومصالحة. ليست الآلية نقل مرة واحدة عاماً ولا بديلاً عن التفويض والاحتفاظ بالمحتوى؛ فلكل أثر حد واضح.

احفظ النية عبر حد معاملة مُدار

يجمع الجزء قدرتي OrderStore و OutboxStore في معاملة مُدارة. insertOrReplay و ensureOrderCreated عقدا تطبيق لا اسما Spring Data سحريان. يجب أن يفرض التنفيذ الهوية الفريدة المقيدة والتكافؤ والذرية؛ ولم ينفذ الجزء ولا يثبتها وسمه.

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

java نية عمل وصندوق ذرية محلية توضيحية
package training.catalog;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

record OutboxHint(long orderId) {}

@Service
class OrderApplication {
    private final OrderStore orders;
    private final OutboxStore outbox;
    private final ApplicationEventPublisher events;
    OrderApplication(OrderStore orders, OutboxStore outbox, ApplicationEventPublisher events) {
        this.orders=orders; this.outbox=outbox; this.events=events;
    }
    @Transactional
    public Receipt place(TrustedOrderCommand command) {
        Receipt receipt=orders.insertOrReplay(command);
        outbox.ensureOrderCreated(receipt, command.operationKey());
        events.publishEvent(new OutboxHint(receipt.orderId()));
        return receipt;
    }
}

يلزم أن يشترك المخزنان بالمعاملة ويفرضا الهوية؛ وليس التلميح المحلي السجل الدائم.

التلميح المحلي بعد التثبيت تحسين فقط

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

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

java تلميح إيقاظ بعد التثبيت توضيحي
package training.catalog;

import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

@Component
class OutboxWakeup {
    private final OutboxDispatcher dispatcher;
    OutboxWakeup(OutboxDispatcher dispatcher) { this.dispatcher=dispatcher; }
    @TransactionalEventListener(phase=TransactionPhase.AFTER_COMMIT)
    void committed(OutboxHint hint) { dispatcher.signal(); }
}

يبقى الماسح الدائم مطلوباً؛ ولم ينفذ حدث أو موزع، و signal قدرة مخصصة لا ضمان تسليم.

بيّن لماذا لا تثبت ذاكرة منع التكرار الدوام

يعالج نموذج Java e1,e1,e2 بمجموعة محلية ثم يحاكي فقد المجموعة وحدها مع بقاء عد الأثر، فترفع إعادة e1 العدد من اثنين لثلاثة. هذا مثال حتمي فعلي ضد اعتبار الذاكرة سجلاً دائماً، لا محاكاة انهيار أواختبار معاملة.

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

java مثال مضاد مستقل لدوام منع التكرار الذاكري
public class Main {

 public static void main(String[] args) throws Exception {
var seen=new java.util.HashSet<String>();
int applied=0;
for(String event:java.util.List.of("e1","e1","e2")) if(seen.add(event)) applied++;
System.out.println("first_pass "+applied);
seen.clear();
if(seen.add("e1")) applied++;
System.out.println("after_memory_loss "+applied);
 }
}
الناتج المتوقع
first_pass 2
after_memory_loss 3

يسمح مسح ذاكرة المنع بتكرار أثر في النموذج دون انهيار أوحفظ أوتسليم خارجي فعلي.

اختبر كل فجوة غموض لا النجاح فقط

اختبر الفشل قبل التثبيت وبعده قبل التنبيه وبعد التسليم قبل التأكيد والتكرار واختلاف المحتوى وإعادة العامل ونفاد المحاولات. افحص الحالة والنية لا عبارة«نُشر»فقط. يلزم الحد المُدار لاختبار الأحداث والوكلاء في تكامل مخول معزول.

لا تبدأ قاعدة أوسيطاً أورسالة أودفعاً هنا. أظهر مخزن الذرية والأثر الذي يحتاج مصالحة. ميّز للمستدعي المرفوض والمقبول والمثبت والمنتظر والمكتمل والمجهول؛ فجمعها في نجاح واحد يجعل الاسترداد والتواصل غير موثوقين مهما بدا المسار السعيد بسيطاً.

الأخطاء الشائعة وإصلاحها

اختفى حدث بعد إعادة البدء.

لماذا يحدث؟
حملت الذاكرة وحدها النية.
كيف تصلحه؟
احفظها مع العمل وأعد المسح.
كيف تتجنب تكراره؟
اختبر فجوة التثبيت والإرسال.

كرر المستهلك تعديلاً.

لماذا يحدث؟
لم تنسق الهوية والأثر والتأكيد دائماً.
كيف تصلحه؟
اختر هوية وتصميماًذرياًمراجعاً.
كيف تتجنب تكراره؟
اختبر فشل ما بعد التسليم.

أعاد مفتاح نتيجة عملية أخرى.

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

اختبر فهمك

1. لماذا لا يضمن الصندوق التسليم مرة واحدة؟

اعرض الحل المشروح

قد يطبق المستلم ثم يفقد التأكيد فتعاد الرسالة. تحفظ النية الاسترداد ويظل المستهلك محتاجاً لمنع أو مصالحة؛ افصل النقل من الأثر.

2. هل يغير العميل المفتاح عند فقد التأكيد؟

اعرض الحل المشروح

لا؛ احفظه وصالح النتيجة. قد ينشئ الجديد طلباًثانياً بعد نجاح الأول. افصل المجهول منالرفض والتراجع المؤكدين.

أهم ما تعلمته

  • تختلف المعاملة المحلية من التسليم البعيد.
  • تمكّن الهوية الدائمة المصالحة.
  • ليس callback بعد التثبيت سجل الاسترداد الوحيد.

المراجع الرسمية