شرح صفوف ومحتوى الفقرة
رغم روعة القراءة غير الحاجزة في التقارير، فإن الاعتماد على جملة SELECT عادية قبل تعديل رصيد أو حجز مقعد طيران يؤدي إلى ثغرة تضارب شهيرة تُعرف باسم ضياع التحديث (Lost Update)؛ إذ تقرأ جلستان في نفس اللحظة أن المقعد متاح (is_booked = 0) فتحجزانه معاً لمستخدمين مختلفين! لمنع هذا التضارب، نستخدم القراءة القافلة للصفوف:
SELECT ... FOR UPDATE;: يفرض قفلاً حصرياً (Exclusive X Lock) على الصفوف المطابقة؛ فلا تستطيع أي معاملة أخرى تعديل الصف رقم14أو قفله حتى تعتمد معاملتك الحالية أو تتراجع عنها.SELECT ... FOR SHARE;: يفرض قفلاً مشتركاً (Shared S Lock) في MySQL 8، فيسمح للجلسات الأخرى بقراءة الصف ولكنه يمنع أي جلسة من تعديله أو حذفه.- أهمية الفهرس في قفل الصفوف: يضع محرك
InnoDBالأقفال على سجلات الفهرس (Index Records)؛ لذا احرص دائماً على أن يعتمد شرطWHEREمعFOR UPDATEعلى عمود مفهرس، لأن غياب الفهرس يضطر المحرك لقفل جميع صفوف الجدول أثناء المسح الكامل.
+---------+-------------+-----------+
| seat_id | flight_code | is_booked |
+---------+-------------+-----------+
| 14 | RJ-402 | 0 |
+---------+-------------+-----------+
SQL
START TRANSACTION;
SELECT seat_id, flight_code, is_booked
FROM flight_seats
WHERE seat_id = 14 AND is_booked = 0
FOR UPDATE;
UPDATE flight_seats SET is_booked = 1 WHERE seat_id = 14;
COMMIT;