حالات الجمود: الكشف والتجنب
افهم كيفية حدوث حالات الجمود، وكيف يكتشفها Postgres، وصمّم قواعد لترتيب الأقفال تمنعها
حالات الجمود: الكشف والتجنب درس مجاني في SQL Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Academy 4 دروس في المجموع.
ما هو الجمود؟
تمسك كل من معاملتين بقفل تحتاج إليه الأخرى، فلا تتمكن أي منهما من المتابعة. تكتشف قاعدة البيانات الدورة وتُجهض إحدى المعاملتين.
جمود شائع
تقفل المعاملة A الصف 1، وتقفل المعاملة B الصف 2. تطلب A الصف 2، وتطلب B الصف 1. فتتوقف المعاملتان.
-- Tx A:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- waiting for B...
-- Tx B:
BEGIN;
UPDATE accounts SET balance = balance - 50 WHERE id = 2;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
-- waiting for A...
-- ERROR: deadlock detectedتكتشف PostgreSQL حالات الجمود
كل deadlock_timeout (وقيمته الافتراضية ثانية واحدة)، تتحقق PostgreSQL من دورات الأقفال. وإذا وجدت دورة، تُجهض إحدى المعاملتين بالرمز 40P01.
ERROR: deadlock detected
DETAIL: Process 1234 waits for ShareLock on transaction 5678 ...قاعدة ترتيب الأقفال
الحل: احرصوا دائمًا على الحصول على الأقفال بالترتيب نفسه في جميع مسارات تنفيذ التعليمات البرمجية.
-- Always update the lower id first:
UPDATE accounts SET balance = balance - 100 WHERE id = LEAST(:from, :to);
UPDATE accounts SET balance = balance + 100 WHERE id = GREATEST(:from, :to);حالات الجمود في الصفوف كثيرة الاستخدام
غالبًا ما تؤدي التحديثات السريعة للصفوف نفسها كثيرة الاستخدام إلى الانتظار على الأقفال، لا إلى الجمود. استخدموا قوائم الانتظار، أو قسّموا الصف كثير الاستخدام، أو نفّذوا التحديثات بالتتابع في شفرة التطبيق.
تقرأ FOR UPDATE الصفوف مع قفلها
احصلوا على أقفال الكتابة وقت القراءة لتجنب المفاجآت لاحقًا:
BEGIN;
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
-- both rows locked in id order
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;تخطي الصفوف المقفلة
لنمط "الحصول على أي صف متاح" في جداول قوائم الانتظار:
SELECT * FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- skips rows other workers have lockedNOWAIT
يفشل فورًا بدلًا من الانتظار:
SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR: could not obtain lock on row in relation "accounts"تشخيص حالات الجمود
ارفعوا قيمة log_lock_waits وسجّلوا سياق الجمود في السجل. ويعرض إدخال السجل المعاملتين واستعلاماتهما.
حلقة إعادة المحاولة في التطبيق
يمكن التعافي من حالات الجمود — أعيدوا محاولة المعاملة التي أُجهضت:
for (let attempt = 0; attempt < 3; attempt++) {
try {
await runTransaction();
break;
} catch (e) {
if (e.code === '40P01') continue; // deadlock
throw e;
}
}تقليل نطاق الأقفال
قصّروا مدة المعاملات — إذ يبقى كل صف تم الوصول إليه مقفلاً حتى COMMIT. لا تنفذوا طلبات HTTP أو عمليات حسابية طويلة داخل المعاملة.
فهرسة المفاتيح الخارجية لتجنب تصعيد الأقفال
عند حذف سجل أب، يتم التحقق من كل صف تابع له. ومن دون فهرس FK، يتطلب ذلك فحص الجدول كاملًا، بالإضافة إلى أقفال الصفوف. افهرسوا كل عمود FK.
مراجعة
تحدث حالات الجمود — لذا صمّموا النظام لتقليلها.
- احصلوا على الأقفال بترتيب متسق
- استخدموا FOR UPDATE مبكرًا للتصريح بالنية
- استخدموا SKIP LOCKED مع قوائم الانتظار
- أعيدوا المحاولة عند أخطاء الجمود (40P01)
- أبقوا المعاملات قصيرة
تحقق سريع
ما مبدأ التصميم الأكثر موثوقية لمنع حالات الجمود؟
الأسئلة الشائعة
هل درس «حالات الجمود: الكشف والتجنب» مجاني؟
نعم — نص درس «حالات الجمود: الكشف والتجنب» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Academy، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Academy 4 دروس في المجموع.
ماذا ستتعلم في «حالات الجمود: الكشف والتجنب»؟
افهم كيفية حدوث حالات الجمود، وكيف يكتشفها Postgres، وصمّم قواعد لترتيب الأقفال تمنعها تتمرن على SQL Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Academy؟
لا تُشترط خبرة سابقة. SQL Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «حالات الجمود: الكشف والتجنب»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Academy هذا؟
نعم. كل درس في SQL Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- خصائص ACID والحالات الشاذة
- مستويات العزل: READ COMMITTED وREPEATABLE READ وSERIALIZABLE
- حالات الجمود: الكشف والتجنب
- القفل التفاؤلي مقابل القفل التشاؤمي