MySQL: آليات القفل في MySQL ومبادئ التحكم في التزامن…

آخر تحديث: 2026-08-26

تُعد الأقفال جوهر التحكم في التزامن — فلا يمكنك كتابة كود متزامن فعال إلا من خلال فهم كيفية عمل الأقفال.

يشرح هذا الدرس آلية القفل في MySQL.

1. ما ستتعلمه



2. أنواع الأقفال

100%
graph TB
    A[MySQL Locks] --> B[By Granularity]
    A --> C[By Type]
    B --> D[Table Lock Table Lock]
    B --> E[Row Lock Row Lock]
    B --> F[Page Lock]
    C --> G[Shared Lock S Lock]
    C --> H[Exclusive Lock X Lock]
    C --> I[Intent Lock Intention Lock]
البعد قفل الجدول قفل الصف
مستوى التفصيل الجدول بأكمله صف واحد
احتمالية نشوب نزاع عالية منخفضة
أداء التزامن منخفض مرتفع
التكلفة منخفضة مرتفعة
المحرك MyISAM/InnoDB InnoDB


3. الأقفال المشتركة والأقفال الحصرية

(1) القفل المشترك (S Lock)

SQL
-- Acquire a shared lock (read lock) — MySQL 8.0+ Recommended Syntax
SELECT * FROM users WHERE id = 1 FOR SHARE;

-- MySQL 5.7 old syntax (8.0 deprecated but still usable)
-- SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;

-- Other transactions can read, but cannot write

(2) القفل الحصري (X Lock)

SQL
-- Set an exclusive lock (write lock)
SELECT * FROM users WHERE id = 1 FOR UPDATE;

-- Other transactions cannot read (if also locked) or write
نوع القفل القراءة الكتابة
قفل مشترك S
قفل حصري X


4. قفل النية

قفل النية هو قفل على مستوى الجدول يُستخدم لتحديد ما إذا كان صف ما في الجدول مقفلاً أم لا بسرعة.

قفل النية الوصف
IS (قفل مشترك مقصود) تهدف المعاملة إلى وضع قفل من النوع S على الصف
IX (قفل حصري مقصود) تهدف المعاملة إلى وضع قفل من النوع X على الصف

الغرض: عند الحصول على قفل جدول، لا داعي للتحقق من كل صف على حدة؛ بل يكفي التحقق من القفل المقصود فقط.

▶ مثال: التطبيقات العملية للأقفال

SQL
-- Session 1: Set an exclusive lock
START TRANSACTION;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
-- At this moment id=1 is locked

-- Session 2: Try updating (Waiting)
UPDATE accounts SET balance = 500 WHERE id = 1;
-- Wait until Session 1 commits or times out

-- Session 1: Commit
COMMIT;
-- Session 2 execution succeeds
▶ جرّب الكود

5. MVCC (التحكم في التزامن متعدد الإصدارات)

تتيح تقنية MVCC إجراء عمليات القراءة دون حجز من خلال الاحتفاظ بإصدارات متعددة من البيانات.

(1) كيف يعمل نظام MVCC

100%
graph LR
    A[Current Data] --> B[Undo Log<br/>History of Versions]
    B --> C[v1] --> D[v2] --> E[v3]
    F[Read View] -->|Based on the quarantine level| G[Which version to read?]

(2) سلوك القراءة لمستويات العزل المختلفة

مستوى العزل وضع القراءة
قراءة غير ملتزمة تقرأ دائمًا أحدث البيانات (قد يؤدي ذلك إلى قراءة غير نظيفة)
القراءة المخصصة إنشاء عرض قراءة جديد لكل أمر SELECT
القراءة القابلة للتكرار إنشاء طريقة عرض للقراءة في بداية المعاملة
قابل للتسلسل قراءة مقفلة


6. حالة التعطل

(1) ما هو المأزق؟

هناك معاملتان تنتظر كل منهما الأخرى لرفع القفل:

SQL
-- TransactionsA
START TRANSACTION;
UPDATE accounts SET balance = 100 WHERE id = 1;  -- Lock id=1
UPDATE accounts SET balance = 200 WHERE id = 2;  -- Waiting for id=2

-- Transaction B
START TRANSACTION;
UPDATE accounts SET balance = 300 WHERE id = 2;  -- Lock id=2
UPDATE accounts SET balance = 400 WHERE id = 1;  -- Waiting for id=1 (Deadlock!)

(2) معالجة حالات التعطل

SQL
-- View deadlock information
SHOW ENGINE INNODB STATUS\G

-- Set the lock wait timeout (seconds)
SET innodb_lock_wait_timeout = 50;  -- seconds

(3) تجنب حالات التعطل

الاستراتيجية الوصف
الترتيب الثابت الوصول إلى الجداول والصفوف بنفس الترتيب
تقليل مدة الاحتفاظ بالقفل تنفيذ المعاملات في أسرع وقت ممكن
استخدام مستوى عزل أقل عدد أقل من أقفال READ COMMITTED
إنشاء الفهارس بحكمة تقليل نطاق القفل


7. مهلة انتظار القفل

SQL
-- View Lock Wait Timeout
SELECT @@innodb_lock_wait_timeout;

-- Settings (seconds)
SET innodb_lock_wait_timeout = 10;

-- Timeout Error
-- ERROR 1205: Lock wait timeout exceeded


❓ أسئلة شائعة

س هل يستخدم InnoDB أقفال الجداول أم أقفال الصفوف؟
ج بشكل افتراضي، يستخدم أقفال الصفوف (القائمة على الفهرس). وفي حالة عدم وجود فهرس، يلجأ إلى أقفال الجداول.
س هل تقوم عبارة SELECT بالحصول على قفل؟
ج لا تحصل عبارة SELECT العادية على قفل (قراءة لقطة MVCC). أما SELECT ... FOR UPDATE فتحصل على قفل حصري، وSELECT ... FOR SHARE (MySQL 8.0+) فتحصل على قفل مشترك. وقد تم إهمال الصيغة القديمة LOCK IN SHARE MODE في الإصدار 8.0.
س كيف يمكنني عرض عمليات القفل الحالية؟
ج SELECT * FROM performance_schema.data_locks; (MySQL 8.0)
س هل يستخدم InnoDB أقفال الجداول أم أقفال الصفوف؟
ج بشكل افتراضي، يستخدم أقفال الصفوف، والتي يتم تنفيذها استنادًا إلى الفهارس. وفي حالة عدم وجود فهارس، يلجأ إلى أقفال الجداول.
س هل تقوم عبارة SELECT بالحصول على قفل؟
ج لا تحصل عبارة SELECT العادية على قفل (قراءة لقطة MVCC)؛ أما عبارة FOR UPDATE فتحصل على قفل حصري؛ وعبارة FOR SHARE فتحصل على قفل مشترك.

📖 ملخص


📝 تمارين

  1. سؤال أساسي (مستوى الصعوبة: ⭐): اشرح الفرق بين القفل المشترك والقفل الحصري.

  2. تمرين متقدم (مستوى الصعوبة: ⭐⭐): قم بإنشاء سيناريو لتعطل التزامن (deadlock) ولاحظ كيف يتعامل MySQL معه.

  3. سؤال التحدي (مستوى الصعوبة: ⭐⭐⭐): قارن سلوك عمليات القراءة والكتابة المتزامنة في ظل مستويات عزل مختلفة.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%