labZero:~$ cd ./lab / lab-broadcasting-after-c...
Broadcasting داخل transaction — الـ frontend يستقبل الحدث قبل حفظ البيانات
Event أُطلق داخل DB::transaction لم تكتمل — الـ frontend طلب البيانات وحصل على 404 لأن commit جاء بعده.
السياق
نظام طلبات مع لوحة real-time. OrderCreated event يُطلق داخل DB::transaction(). Laravel Echo على الـ frontend يستقبل الحدث ويطلب /api/orders/{id} فوراً — يحصل على 404 في ~15% من الحالات. Transaction لم تكتمل بعد.
الإجراء
أضفت Log::info قبل وبعد commit وداخل الـ job. النتيجة: الـ job ينطلق بعد dispatch() مباشرة، ليس بعد commit. ثلاثة حلول: (1) afterCommit: true في config/queue.php على الـ connection — يؤجّل dispatch لكل jobs تلقائياً، (2) ShouldBeQueued مع afterCommit() في الـ event نفسه، (3) نقل الـ broadcast لـ Observer@created الذي يُستدعى بعد الحفظ. استخدمت log timestamps لإثبات التسلسل.
النتيجة
afterCommit: true في الـ connection config حل المشكلة لكل jobs دون تعديل كل event. Observer@created أكثر تحكماً لكن يربط الـ broadcast بكل save() لا بـ transaction المقصودة فقط. الـ dispatch اليدوي بعد الـ transaction (خارجها) كان الأبسط لحالة بعينها.
الدرس
Broadcasting داخل transaction = race condition مضمون — afterCommit: true ليس خياراً بل إعداد أساسي في أي مشروع يجمع queues وreal-time.