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

Express.js / المتقدم: عقود الموارد والكتابة والإصدار / الدرس 16

تحمل تكرار الكتابة والنسخ وحدود المعاملة

صمم إعادة كتابة HTTP حول هوية طلب منطقي وتسوية من المصدر المعتمد.

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

أهداف الدرس

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

قد يغيب الرد بعد كتابة محفوظة

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

مرر هويات منفصلة لعملية مجال متماسكة

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

javascript بروتوكول كتابة توضيحي يملكه المجال
app.post("/courses/:id/publish", async (req,res) => {
  const requestKey = validatedRequestKey(req.get("Idempotency-Key"));
  const input = validatedPublishInput(req.body);
  const result = await catalog.publish({
    principal:req.principal,id:req.params.id,requestKey,
    expectedRevision:input.expectedRevision
  });
  return res.status(result.status).json(result.publicBody);
});

التحقق والخدمة اعتمادات غير منفذة. يمرر المسار هويات منفصلة ولا ينفذ إعادة دائمة.

تكون الذرية حيث يحفظ الأثر ونتيجة الإعادة

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

افحص الإعادة المطابقة ورفض الإدخال المتغير محلياً

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

javascript نموذج محلي كامل للإعادة المنطقية
const outcomes=new Map(); let effects=0;
function apply(key,fingerprint) {
  if (outcomes.has(key)) {
    const prior=outcomes.get(key);
    if (prior.fingerprint !== fingerprint) throw new Error("KEY_REUSED");
    return prior.result;
  }
  const result={effect:++effects};
  outcomes.set(key,{fingerprint,result}); return result;
}
console.assert(apply("r1","c1@4").effect === 1);
console.assert(apply("r1","c1@4").effect === 1);
let rejected=false; try {apply("r1","c1@5");} catch {rejected=true;}
console.assert(rejected && effects === 1);

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

تحقق من الآثار بجانب نتيجة HTTP العامة

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

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

تسبب الإعادة أثراً ثانياً للنشر

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

تكتب نسختان متزامنتان

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

يختلط تعديل جديد بإعادة مطابقة

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

اختبر فهمك

1. هل تلغي expectedRevision الحاجة إلى requestKey؟

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

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

2. ماذا لا يثبته نموذج الإعادة المحلي؟

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

لا يثبت الاستمرار أو الفرادة المتزامنة أو التعافي أو نطاق المستأجر أو HTTP. يفحص خريطة متزامنة للمطابق والمختلف، ويفصل دليله عن دمج المعاملة والمصدر اللازم للبروتوكول الحقيقي.

أهم ما تعلمته

  • تحمي هوية الطلب والنسخة وذرية المعاملة جوانب مختلفة.
  • لا يثبت تنسيق خطأ HTTP التراجع أو أمان الإعادة.

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