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

Spring Boot / المتوسط: البيانات والأمان وأدلة الإطار / الدرس 8

وكلاء المعاملة ودلالة الأخطاء

حدد وحدة عمل ذرية وتحقق من تطبيقها بمدخل الوكيل والانتشار وقواعد التراجع ومدير المعاملة.

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

أهداف الدرس

  • شرح أن وجود الوسم ليس دليلاً على المعاملة.
  • اختيار التراجع والانتشار وفق العقد.
  • حفظ الفشل وفحص الحالة المثبتة مستقلة.

اختر ما يجب تثبيته معاً

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

قصّر العمر وأبعد المستخدم والاتصال البطيء عن الموارد المحجوزة. حدد مالك الإكمال والخطأ؛ فعودة جسم الخدمة لا تثبت نجاح تثبيت الاستدعاء عبر الوكيل، وقد يفشل flush أو commit بعده. احفظ السبب ولا تحول الفشل إلى رد نجاح يخفي نتيجة العمل.

اعبر الحد المُدار للوحدة المعلنة

يفوض الجزء شروط المجال لدوال Account ويعلن معاملة خدمة واحدة، لكنه يحتاج مستودعاً وكياناً ومديراً وعزلاً وتزامناً مناسبين. لم ينفذ ولا يثبت منع ضياع التحديث بمجرد Transactional؛ فتبقى النسخة والقفل والشروط والقيود من الثابت.

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

java حد تحويل توضيحي يملك المعاملة
package training.catalog;

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

@Service
class TransferService {
    private final AccountRepository accounts;
    TransferService(AccountRepository accounts) { this.accounts = accounts; }

    @Transactional
    public void transfer(long from, long to, long cents) {
        if (cents <= 0) throw new IllegalArgumentException("amount");
        Account source = accounts.findById(from).orElseThrow();
        Account target = accounts.findById(to).orElseThrow();
        source.debit(cents);
        target.credit(cents);
    }
}

تحتاج العقود السياقية حفظ الثوابت؛ ولم تُرصد معاملة أوعزل أوتثبيت فعلي.

افصل دخول الوكيل من استدعاء النسخة لنفسها

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

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

java المعاملة المستقلة للدفعة سياسة إكمال جزئي صريحة
package training.catalog;

import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
class ChunkWriter {
    private final ImportRepository rows;
    ChunkWriter(ImportRepository rows) { this.rows = rows; }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void write(List<ImportRow> chunk) { rows.saveAll(chunk); }
}

@Service
class ImportCoordinator {
    private final ChunkWriter writer;
    ImportCoordinator(ChunkWriter writer) { this.writer = writer; }
    public void run(List<List<ImportRow>> chunks) {
        for (var chunk : chunks) writer.write(chunk);
    }
}

تعبر النداءات حدود كائنات مُدارة، ويحتاج أثرها تكاملاً وتخزيناً؛ ولم تُنفذ.

افهم rollback-only و read-only بدقة

قد تجعل عملية مشاركة المعاملة rollback-only، ولا يعيد التقاط خطئها قابلية التثبيت بالضرورة؛ فقد يظهر UnexpectedRollbackException عند الإكمال. افهم الملكية والسياسة ولا تبتلع خطأ ثانياً وتعلن النجاح. وتختلف REQUIRES_NEW أو نقاط الحفظ في المعنى والدعم.

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

تحقق من الوكيل والنتيجة المخزنة فعلاً

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

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

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

لم تتحقق المعاملة المتوقعة لدالة موسومة.

لماذا يحدث؟
تجاوز النداء الوكيل أو اختيرت دلالة غير مدعومة.
كيف تصلحه؟
افحص المستدعي والوكيل والرؤية والمدير.
كيف تتجنب تكراره؟
اختبر الحد المُدار.

UnexpectedRollbackException

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

بقيت تغييرات بعد فشل متحقق.

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

اختبر فهمك

1. لماذا لا تكفي REQUIRES_NEW لمساعد تستدعيه النسخة؟

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

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

2. ماذا يفحص بعد التقاط فشل REQUIRED وعودة الخارج طبيعية؟

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

حالة rollback-only ونتيجة الإكمال. ليس التقاط Java تعافياً للمعاملة؛ احفظ الفشل وافحص القاعدة ولا تسبق الوكيل بإعلان نجاح.

أهم ما تعلمته

  • تسبق وحدة العمل اختيار الانتشار.
  • يحدد الوكيل وسياسة التراجع أثر الوسم.
  • يتحقق التثبيت والتراجع بدليل تخزين مضبوط.

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