حل تعارضات المزامنة دون اتصال يبدأ بالاعتراف بأن جهازين قد يملكان حقيقتين مؤقتتين عن السجل نفسه. عندما يعود الاتصال، لا يكفي إرسال آخر نسخة أو الاعتماد على ساعة الجهاز. يجب أن يعرف الخادم ما الذي قصده المستخدم، وما الإصدار الذي رآه، وما الحقول التي تغيرت، وما المخاطر إذا دُمجت أو رُفضت.
هذا الدليل يركز على قرار التعارض وتجربة الاسترداد. يشرح دليل PWA التي تعمل دون اتصال التخزين والطابور ودورة Service Worker، بينما ندخل هنا في النسخ والعمليات وسياسات الدمج وسجل القرار عبر تطبيق ويب أو موبايل.
عرّف وحدة التزامن
قرر هل يزامن العميل سجلاً كاملاً أم حقولاً أم أوامر ذات معنى مثل «أكمل المهمة» أو «أضف كمية». الأوامر الدلالية غالباً أوضح من رفع نسخة JSON كاملة، لأنها تحفظ نية المستخدم وتسمح للخادم بتطبيق قاعدة العمل.
لكل عملية معرف فريد وإصدار حمولة وممثل ومستأجر ووقت إنشاء محلي وترتيب واعتماديات وإصدار قاعدة شاهده المستخدم. لا تستخدم وقت الجهاز وحده للحسم؛ يمكن أن يكون خاطئاً أو يتغير.
استخدم إصداراً أو شرطاً مسبقاً
أرسل version أو ETag أو قيمة تحقق تمثل النسخة المقروءة. عند التعديل، يقبل الخادم العملية إذا كانت ما تزال على الإصدار المتوقع، أو يعيد تعارضاً مع الحد الأدنى من السياق المسموح. هذا يمنع الكتابة العمياء.
لا تجعل رقم الإصدار قابلاً للتعديل من المستخدم. حدثه داخل معاملة مع السجل. اختبر طلبين متزامنين على الإصدار نفسه؛ يجب أن ينجح واحد وفق القاعدة ويأخذ الآخر مسار تعارض.
افصل التكرار عن التعارض
إعادة إرسال العملية نفسها بعد مهلة ليست تعارضاً؛ هي duplicate يجب أن يعيد النتيجة السابقة من دون أثر جديد. أما عمليتان مختلفتان انطلقتا من النسخة نفسها فهما مرشحتان للتعارض. استخدم معرف العملية لـidempotency وإصدار السجل للكشف.
إذا خلطت الاثنين، قد تعرض حوار تعارض بعد retry طبيعي أو تطبق العملية مرتين. احتفظ بنتيجة معالجة العملية ضمن مدة وسياسة، وتحقق أن المعرف لا يعاد استخدامه مع حمولة مختلفة.
صنّف الحقول حسب قابلية الدمج
بعض البيانات تراكمية، مثل إضافة ملاحظة مستقلة؛ وبعضها مجموعة يمكن دمج عناصرها؛ وبعضها قيمة حصرية مثل موعد أو حالة موافقة؛ وبعضها مالي أو مخزون يحتاج سلطة خادم أو مراجعة. اكتب السياسة لكل نوع، لا لكل شاشة.
لا تفترض أن النص يمكن دمجه تلقائياً لمجرد أنه نص. ملاحظة طبية أو تعليمات قد تفقد المعنى إذا جمع مقطعان. لا تستخدم last-write-wins إلا عندما يقبل المنتج فقدان تعديل أقدم ويستطيع شرحه.
صمم الأوامر لتكون قابلة للتحويل
بدلاً من «اجعل المخزون 8»، قد يكون «استهلك وحدتين من العملية X» أكثر قابلية للتطبيق على حالة أحدث، مع تحقق عدم النزول تحت الحد. وبدلاً من رفع قائمة مهام كاملة، أرسل «أكمل البند Y». القرار يعتمد المجال وليس قاعدة عامة.
احتفظ بإصدار الأمر ومهاجر له عند تطور التطبيق. جهاز بقي دون اتصال أسبوعاً قد يرسل حمولة قديمة. إذا لم يمكن تحويلها بأمان، أوقفها للمراجعة ولا تسقطها.
حدّد سلطة الخادم
يملك الخادم قواعد التفويض والقيود العالمية والرصيد والحجوزات المشتركة. يمكن للعميل حفظ نية مؤقتة، لكنه لا يضمن قبول مقعد أو كمية أو دفعة. اكتب للمستخدم «محفوظ على الجهاز» و«قُبل في النظام» كحالتين مختلفتين.
عند رفض القاعدة، أعد رمزاً مستقراً ورسالة آمنة والبيانات اللازمة للقرار. لا ترسل سجل مستخدم آخر لتفسير التعارض. تحقق من الصلاحية من جديد وقت المزامنة؛ قد يتغير الدور أثناء الانقطاع.
ابنِ صندوق تعارضات
كل تعارض يحتاج العملية المحلية، والنسخة الحالية المسموح عرضها، والحقول المختلفة، والخيارات، وموعد الإنشاء والمالك. لا تحذف العملية من الطابور عند أول 409. انقلها إلى needs_attention واحتفظ بها حتى قرار أو انتهاء سياسة معلن.
رتب الصندوق حسب الأثر والعمر. قد يحل الفني تعارض ملاحظة، بينما يحتاج تعديل مالي مديراً. امنع المستخدم من تطبيق قرار على سجل تغير مجدداً؛ القرار نفسه يرسل بشرط إصدار جديد.
صمم واجهة توضح الفرق
اعرض «تعديلك» و«الحالة الحالية» بعناوين ومعاني، لا JSON. ميز الحقول التي تغيرت ومن مصدر معروف ووقت الخادم. قدم خيارات مثل الاحتفاظ بالحالي، أو تطبيق تعديل محدد، أو إنشاء سجل منفصل، وفق السياسة.
لا تستخدم زر «استبدل» عاماً للمال أو الموعد. اختبر العربية وRTL والنص الطويل وإمكانية الوصول. اسمح بنسخ مرجع دعم، لا الحمولة الحساسة. إذا لم يملك المستخدم صلاحية القرار، أنشئ مهمة لمراجعه واشرح أن العمل محفوظ.
تعامل مع الحذف كحالة
قد يعدل جهاز سجلاً حُذف أو أُرشف على الخادم. احتفظ بـtombstone أو إصدار حذف مدة تكفي لطابور متوقع، بدلاً من نسيان أن المعرف وُجد. قرر هل يستعاد السجل أو ترفض العملية أو تنشئ نسخة جديدة.
الحذف من جهاز واحد يجب ألا يمحو بيانات حساسة أو مالية من الجميع بلا صلاحية وتأكيد. وفي المقابل، لا تعيد مزامنة سجل حُذف بسبب سياسة أو سحب وصول. اختبر إلغاء الحساب والجهاز غير المتصل.
رتب العمليات التابعة
إنشاء سجل محلي ثم إضافة مرفق ثم إكماله عمليات مترابطة. استخدم معرفات عميل مستقرة وخريطة إلى معرف الخادم، وسجل dependencies. لا ترسل الإكمال قبل نجاح الإنشاء. إذا رفض الأصل، ضع التوابع في حالة واضحة.
اسمح باستئناف الطابور بعد إغلاق التطبيق. لا تعتمد على الذاكرة. عالج كل عملية داخل حدود مناسبة ولا تجعل فشل سجل واحد يمنع سجلات مستقلة، مع الحفاظ على الترتيب حيث يغير المعنى.
عالج الساعات والترتيب بحذر
وقت الجهاز مفيد لعرض متى عمل المستخدم تقريباً لكنه ليس ترتيباً عالمياً موثوقاً. استخدم وقت استقبال الخادم وتسلسلاً أو إصداراً لكل سجل. احفظ المنطقة الزمنية والتوقيت الخام عند الحاجة، ولا تصحح تاريخاً قديماً إلى «الآن».
في الأحداث التي تصل خارج الترتيب، تحقق من الانتقال المسموح. لا تجعل حدث «بدأ» المتأخر يعيد مهمة مكتملة إلى حالة سابقة. ضع قواعد للحالات، وسجل الحدث المرفوض للمراجعة عند الأهمية.
احمِ البيانات المحلية
خزن الحد الأدنى اللازم، وافصل بيانات الحسابات والمستأجرين، وامسح أو اقفل عند تسجيل الخروج أو سحب الجهاز عندما يتصل. لا تعد بحذف عن بعد لجهاز لن يعود. تجنب أسرار طويلة العمر في قاعدة محلية.
شفّر حيث يفيد، لكن اعتبر الجهاز نفسه سطح وصول. امنع نسخ payload الحساس في السجلات أو تقارير الأعطال. اختبر جهازاً مشتركاً ومستخدمين متعاقبين. يشرح دليل أهمية Offline-First كيفية اختيار الأعمال التي تستحق هذه المخاطر.
اختبر مصفوفة التعارض
غطِّ جهازين يعدلان حقلاً واحداً وحقولاً مختلفة، وإعادة العملية نفسها، وعمليتين مختلفتين من إصدار واحد، وحذفاً مقابل تعديل، وتغيير صلاحية، وانتهاء جلسة، وتطبيقاً قديماً، وطابوراً بعد ترقية المخطط، وامتلاء التخزين. اكتب القرار المتوقع لكل حالة.
استخدم شبكة بطيئة ومتقطعة وأغلق التطبيق أثناء المعالجة. اختبر أن الواجهة لا تقول «تمت المزامنة» قبل إقرار الخادم. راقب فقد العمليات والتكرار وعمر أقدم عنصر وعدد التعارضات حسب النوع، بلا تسجيل محتواها.
خطط للدعم والاستعادة
امنح كل عملية مرجعاً يمكن البحث عنه، وسجل انتقالاتها من دون بيانات زائدة. يجب أن يعرف الدعم هل بقيت محلية أو وصلت أو رفضت أو تنتظر قراراً. وفر تصديراً آمناً لحالة الطابور عند الحاجة، ولا تطلب من المستخدم مسح بيانات التطبيق كحل أول.
تقدم خدمة تطوير الويب وPWA مالكاً تجارياً للمزامنة، لكن سياسة التعارض تحتاج صاحب المنتج وخبير المجال. ابدأ بمسار واحد عالي القيمة، ولا تعد أن كل التطبيق يعمل دون اتصال.
الخلاصة: حافظ على نية المستخدم قبل اختيار الفائز
حل التعارض الموثوق يميّز إعادة المحاولة من تعديل منافس، ويكشف النسخة، ويطبق قاعدة تناسب المجال، ويحفظ العمل حتى يصدر قرار واضح. التعديل الأحدث زمنياً ليس دائماً الأصح. اطلب ورشة تصميم تعارضات المزامنة مع ثلاثة سيناريوهات واقعية وأدوار القرار وحدود البيانات المحلية.


