انتقل إلى محتوى الدرس
الدرس 61
دورة MySQL

مستويات عزل المعاملات وأقفال الصفوف في MySQLMySQL Transaction Isolation Levels and Row Locking

تعلّم مستويات عزل المعاملات وأقفال الصفوف في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
أقسام الدرس
6
الأمثلة
5
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
7
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع
مخطط توضيحي لدرس مستويات عزل المعاملات وأقفال الصفوف في MySQL
مخطط توضيحي لدرس مستويات عزل المعاملات وأقفال الصفوف في MySQL

عندما تتعامل مئات الجلسات المتزامنة مع نفس الجداول قراءةً وكتابةً، يحدد معيار SQL القياسي ثلاث ظواهر تزامن (Read Phenomena) صُممت مستويات العزل لمنعها:

  • القراءة المتسخة (Dirty Read): أن تقرأ الجلسة (أ) بيانات عدلتها الجلسة (ب) قبل اعتمادها؛ فإذا نفذت الجلسة (ب) أمر ROLLBACK لاحقاً، تكون الجلسة (أ) قد بنت قرارها على بيانات وهمية.
  • القراءة غير القابلة للتكرار (Non-Repeatable Read): أن تقرأ الجلسة (أ) نفس الصف مرتين داخل معاملة واحدة فتجد قيمته قد تغيرت لأن الجلسة (ب) اعتمدت أمر UPDATE بين القراءتين.
  • القراءة الشبحية (Phantom Read): أن تنفذ الجلسة (أ) استعلام نطاق شرطي مرتين فتظهر صفوف جديدة لم تكن موجودة لأن الجلسة (ب) اعتمدت أمر INSERT ضمن ذلك النطاق.
  • SELECT @@transaction_isolation: يستعلم عن مستوى العزل النشط في الجلسة والخادم (REPEATABLE-READ افتراضياً في MySQL 8).
+-------------------+-------------------+
| session_isolation | global_isolation  |
+-------------------+-------------------+
| REPEATABLE-READ   | REPEATABLE-READ   |
+-------------------+-------------------+
SQL
SELECT @@transaction_isolation AS session_isolation,
       @@global.transaction_isolation AS global_isolation;

START TRANSACTION;
SELECT account_id, balance FROM wallet_ledgers WHERE account_id = 101;
COMMIT;

يتيح لك محرك InnoDB ضبط مستوى العزل للجلسة الحالية عبر الأمر SET SESSION TRANSACTION ISOLATION LEVEL بين أربعة مستويات قياسية مرتبة من الأقل عزلاً إلى الأعلى صرامةً:

  • READ UNCOMMITTED: يسمح بالقراءة المتسخة وغير المتكررة والشبحية؛ نادراً ما يُستخدم في الإنتاج لخطورة قراءة بيانات غير معتمدة.
  • READ COMMITTED: يمنع القراءة المتسخة تماماً، وينشئ لقطة قراءة جديدة مع كل جملة SELECT منفردة داخل المعاملة بحيث ترى أحدث البيانات المعتمدة.
  • REPEATABLE READ (المستوى الافتراضي في InnoDB): يثبت لقطة قراءة موحدة طوال المعاملة منذ أول عملية قراءة، فيمنع القراءة المتسخة وغير المتكررة والشبحية معاً.
  • SERIALIZABLE: أعلى درجات العزل؛ يحوّل جمل SELECT العادية إلى قراءات مقفلة (FOR SHARE) لمنع أي تعديل متزامن، لكنه يقلل سرعة التزامن.
+------------------+
| active_isolation |
+------------------+
| READ-COMMITTED   |
+------------------+
SQL
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

SELECT @@transaction_isolation AS active_isolation;

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

محاكي مستويات العزل وأقفال الصفوف في InnoDB

كيف يستطيع آلاف الزوار تنفيذ استعلامات SELECT في نفس اللحظة التي تجري فيها معاملات UPDATE دون أن يعطل أحدهما الآخر؟ السر يكمن في تقنية التحكم بالتزامن متعدد النسخ (MVCC)؛ إذ يحتفظ محرك InnoDB داخل كل صف بمعرّف المعاملة التي عدلته (DB_TRX_ID) ومؤشر (DB_ROLL_PTR) يشير إلى النسخ التاريخية السابقة للصف في سجل التراجع:

  • القراءة المتسقة غير الحاجزة: لا تضع جمل SELECT العادية أي أقفال على الصفوف؛ بل تقارن معرّف معاملة الصف بلقطة القراءة (Read View) الخاصة بجلستك.
  • استرجاع النسخة التاريخية من Undo Log: إذا كان الصف قد عُدِّل بواسطة معاملة أحدث من لقطتك، يتتبع المحرك مؤشر التراجع لإرجاع النسخة المتسقة كما كانت وقت بدء قراءتك.
  • START TRANSACTION WITH CONSISTENT SNAPSHOT;: ينشئ لقطة القراءة المتسقة منذ اللحظة الأولى لفتح المعاملة دون انتظار أول جملة SELECT.
  • القارئ لا يعطل الكاتب: بفضل MVCC، تعمل القراءات العادية بأقصى سرعة دون إيقاف عمليات الكتابة المتزامنة.
SQL
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION WITH CONSISTENT SNAPSHOT;

SELECT account_id, holder, balance
FROM wallet_ledgers
WHERE account_id IN (101, 102);
COMMIT;

رغم روعة القراءة غير الحاجزة في التقارير، فإن الاعتماد على جملة 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;

عندما تقفل الجلسة الأولى الصف (أ) وتنتظر الصف (ب)، بينما تقفل الجلسة الثانية الصف (ب) وتنتظر الصف (أ)، تنشأ حلقة انتظار دائرية تُسمى الإقفال المتبادل (Deadlock). كما أن انتظار تحرير القفل لمدة 50 ثانية افتراضياً (innodb_lock_wait_timeout) يعطل طوابير المهام السريعة. يوفر MySQL 8 حلولاً هندسية حاسمة:

  • الكشف التلقائي عن الإقفال المتبادل: يكتشف محرك InnoDB حلقة الانتظار الدائرية فوراً ويتراجع عن المعاملة الأصغر حجماً مع إرجاع الخطأ ERROR 1213 (40001): Deadlock found لتتمكن من إعادة محاولتها برمجياً.
  • الوقاية من Deadlock: رتّب دائماً تعديل وقفل الصفوف بترتيب تصاعدي ثابت للمفتاح الأساسي (ORDER BY id ASC) في جميع المعاملات.
  • FOR UPDATE NOWAIT: يرفض الانتظار تماماً ويُرجع خطأ فورياً (ERROR 3572) إذا كان الصف مقفلاً من جلسة أخرى.
  • FOR UPDATE SKIP LOCKED: يتخطى أي صفوف مقفلة حالياً ويقفل أول صف متاح غير مقفل، وهو الحل المثالي لبناء طوابير معالجة المهام (Job Queues) المتوازية في MySQL 8.
SQL
START TRANSACTION;

SELECT job_id, payload, status
FROM job_queue
WHERE status = 'pending'
ORDER BY job_id ASC
LIMIT 1
FOR UPDATE SKIP LOCKED;
COMMIT;

تقارن المصفوفة التالية بين مستويات العزل الأربعة في محرك InnoDB داخل MySQL 8:

مستوى العزلالقراءة المتسخةالقراءة غير المتكررةالقراءة الشبحية (في InnoDB)نطاق لقطة MVCC
READ UNCOMMITTEDممكنةممكنةممكنةلا يوجد (يقرأ البيانات غير المعتمدة)
READ COMMITTEDممنوعةممكنةممكنةلقطة جديدة لكل جملة SELECT
REPEATABLE READ (الافتراضي)ممنوعةممنوعةممنوعة (بأقفال Next-Key)لقطة موحدة طوال المعاملة
SERIALIZABLEممنوعةممنوعةممنوعةيحوّل القراءات إلى أقفال FOR SHARE

ملخص الدرس: تعلمت في هذا الدرس ظواهر القراءة المتزامنة الثلاث، ومستويات العزل الأربعة في محرك InnoDB، وآلية عمل القراءة المتسقة عبر MVCC، وكيفية قفل الصفوف بأوامر FOR UPDATE وNOWAIT وSKIP LOCKED.
الخطوة التالية والدرس القادم: انتقل إلى الوحدة السابعة عشرة «إدارة الخادم» بدءاً من درس «إدارة حسابات المستخدمين والمصادقة في MySQL».

خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

يجمع المستوى الافتراضي REPEATABLE READ في محرك InnoDB بين لقطات MVCC وأقفال الصفوف الدقيقة FOR UPDATE وSKIP LOCKED لتحقيق أعلى درجات الأمان والتزامن. الخطوة التالية: انتقل الآن إلى درس «إدارة حسابات المستخدمين والمصادقة في MySQL».

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Isolation Levels مستويات العزل
تعلّم مستويات عزل المعاملات وأقفال الصفوف في MySQL بأسلوب MySQL 8 الحديث مع أمثلة استعلامات SQL وتطبيقات تفاعلية.
للمراجعة
02 Concurrency Read Phenomena Explained ظواهر القراءة المتوازية الثلاث
المفهوم الهندسي الأساسي والصياغة التطبيقية لقسم ظواهر القراءة المتوازية الثلاث في خادم MySQL 8.4.
للمراجعة
03 Four Isolation Levels in InnoDB مستويات العزل الأربعة بالمحرك
المفهوم الهندسي الأساسي والصياغة التطبيقية لقسم مستويات العزل الأربعة بالمحرك في خادم MySQL 8.4.
للمراجعة
04 Multi Version Concurrency MVCC القراءة المتسقة عبر MVCC
المفهوم الهندسي الأساسي والصياغة التطبيقية لقسم القراءة المتسقة عبر MVCC في خادم MySQL 8.4.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 MVCC MVCC
Multi-Version Concurrency Control
آلية التحكم بالتزامن متعدد النسخ في InnoDB التي تحتفظ بالنسخ السابقة للصفوف في سجل التراجع لتوفير قراءة متسقة غير حاجزة.
للمراجعة
02 X Lock X Lock
Exclusive Row Lock
قفل الصف الحصري الذي يُحجز عبر FOR UPDATE أو UPDATE ويمنع الجلسات الأخرى من تعديل الصف أو قفله.
للمراجعة
03 S Lock S Lock
Shared Row Lock
قفل الصف المشترك الذي يُحجز عبر FOR SHARE ويسمح بالقراءة المشتركة مع منع تعديل الصف حتى انتهاء المعاملة.
للمراجعة
04 TRX TRX
Database Transaction Identifier
معرّف المعاملة الداخلي في محرك InnoDB الذي يُختم على كل صف لتحديد مدى رؤيته في لقطات MVCC.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. نفّذ جمل SQL الواردة في قسم ظواهر القراءة المتوازية الثلاث داخل بيئة MySQL 8 المحلية وتحقق من المخرجات.

  2. جرّب الحالات الثلاث داخل محاكي مستويات العزل وأقفال الصفوف في InnoDB في قسم مستويات العزل الأربعة بالمحرك وقارن سلوك المحرك.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

6أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي6 أسئلة تنتظرك
01

ما مستوى عزل المعاملات الافتراضي في محرك التخزين InnoDB داخل خادم MySQL 8؟

المستوى الافتراضي لعزل المعاملات في محرك InnoDB هو REPEATABLE READ.

02

بفضل تقنية MVCC في محرك InnoDB، لا تعطل جمل القراءة العادية (SELECT) عمليات التحديث المتزامنة (UPDATE) على نفس الصفوف.

صواب؛ تقرأ جمل SELECT العادية من لقطة MVCC عبر سجل التراجع دون وضع أقفال تعطل الكاتبين.

03

أي ظاهرة تزامن تحدث عندما تقرأ الجلسة (أ) تعديلات غير معتمدة من الجلسة (ب) ثم تتراجع الجلسة (ب) عنها لاحقاً؟

قراءة بيانات غير معتمدة من جلسة أخرى تُسمى القراءة المتسخة (Dirty Read).

04

أي عبارة تُضاف لنهاية استعلام SELECT لحجز قفل حصري (X Lock) على الصفوف المستهدفة ومنع حجزها المزدوج؟

تضع العبارة FOR UPDATE قفلاً حصرياً على الصفوف المطابقة حتى انتهاء المعاملة.

05

أي خيار في MySQL 8 يسمح لعامل طابور المهام بتجاوز الصفوف المقفلة حالياً وقفل المهمة المتاحة التالية فوراً دون انتظار؟

يتجاوز الخيار FOR UPDATE SKIP LOCKED الصفوف المحتجزة ويسحب أول صف متاح غير مقفل فوراً.

06

عندما يكتشف محرك InnoDB إقفالاً متبادلاً (Deadlock) بين معاملتين، فإنه يتراجع تلقائياً عن إحداهما ويُرجع الخطأ رقم 1213.

صواب؛ يفك محرك InnoDB حلقة الانتظار الدائرية تلقائياً بالتراجع عن إحدى المعاملتين وإرجاع الخطأ 1213.