MariaDB / المتوسط: التزامن وSQL القابلة لإعادة الاستخدام / الدرس 7
المعاملات واللقطات والأقفال
نسق تحويلاً بين حسابين واستدل على الجلسات المتزامنة، وافصل قراءة اللقطة عن القراءة المقفلة وصمم إعادة محاولة محدودة.
في هذه الصفحة
أهداف الدرس
- تحديد حدود المعاملة الذرية وتوقعات العزل.
- معالجة التعارض الدائري ومهلة القفل دون آثار تجارية جزئية.
حدث تجاري واحد ومعاملة واحدة
التحويل ليس عبارتي UPDATE مستقلتين؛ يجب حفظ الخصم والإضافة معاً على جداول معاملاتية والتحقق من وجود الحسابين وكفاية المال. يجعل autocommit كل كتابة معاملة مستقلة خلاف ذلك. أبقِ اتصالات الشبكة الخارجية خارج مدة القفل حتى لا تحتجز بوابة دفع بطيئة أقفال الحسابات. إذا انقطع الاتصال أثناء COMMIT فقد تصبح النتيجة غير مؤكدة؛ يساعد سجل عدم تكرار الأثر على حسمها بأمان.
اقفل بترتيب متوقع
افترض حسابي تدريب 10 و20 برصيدين 100 و40. اقفلهما بترتيب المعرف وتحقق من وجودهما وقدرة الحساب 10 على دفع خمسة عشر قبل الكتابة. يعرض الاستعلام التوضيحي 85 و55 ويحافظ على المجموع 140. يعيد ROLLBACK العينة إلى أصلها. التعليقات قرارات يجب أن ينفذها التطبيق، وليست ادعاء بأن SQL ترفض تلقائياً وجهة غير موجودة.
START TRANSACTION;
SELECT account_id, balance FROM accounts
WHERE account_id = 10 FOR UPDATE;
SELECT account_id, balance FROM accounts
WHERE account_id = 20 FOR UPDATE;
-- Application verifies two rows and sufficient balance before continuing.
UPDATE accounts SET balance = balance - 15 WHERE account_id = 10;
UPDATE accounts SET balance = balance + 15 WHERE account_id = 20;
SELECT account_id, balance FROM accounts
WHERE account_id IN (10, 20) ORDER BY account_id;
ROLLBACK;
Expected before rollback: (10, 85), (20, 55).
الحسابان صفان في InnoDB، ويفترض المثال نجاح فحوص الشروط السابقة.
اللقطات لا تحجز حقوق العمل
يكون REPEATABLE READ غالباً المستوى الافتراضي في InnoDB. تستخدم القراءات المتسقة العادية لقطة المعاملة التي تؤسسها أول قراءة متسقة، بينما يأخذ READ COMMITTED لقطة جديدة لكل عبارة من هذا النوع. قد تعرض اللقطة رصيداً محفوظاً أقدم دون منع الكاتب الآخر. تطلب SELECT ... FOR UPDATE قراءة مقفلة داخل معاملة بقواعد رؤية مختلفة. تكرار SELECT العادي لا يحجز المخزون ولا يضمن سلامة قرار لاحق.
صف ترتيب الأحداث لا زمناً ثابتاً
المقطع للجلسة A في مختبر مضبوط من جلستين. بعد أخذ القفل ينتظر UPDATE منافس للحساب 10 من B عادة حتى تنتهي معاملة A. وقد يقرأ SELECT متسق عادي في B نسخة محفوظة وفق العزل. قد تستخدم شروط المجالات أقفال الفجوات أو المفتاح التالي حسب العزل ومسار الوصول. تختلف أقفال سجلات الفهرس عن أقفال البيانات الوصفية؛ شخص الانتظار بدلاً من وصف كل تأخير بقفل جدول.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT account_id, balance FROM accounts
WHERE account_id = 10 FOR UPDATE;
-- A concurrent writer of account 10 waits here.
ROLLBACK;
تطبق SET TRANSACTION دون SESSION على المعاملة التالية، ولا تغير إعداداً عاماً.
عامل التعارض كنتيجة متوقعة
ينشأ التعارض الدائري عندما تنتظر المعاملات بعضها في دائرة؛ يختار InnoDB ضحية لتمكين التقدم. أعد الحدث التجاري كاملاً بعد التراجع مع حد للمحاولات وتأخير متغير. قد يختلف نطاق التراجع عند المهلة عن التعارض بحسب الإعداد، لذا أنهِ المعاملة الفاشلة صراحة. تسبب عبارات تعريف كثيرة حفظاً ضمنياً. تسمح نقطة الحفظ بتراجع جزئي لعمل معاملاتي لكنها لا تجعل تغيير المخطط قابلاً للتراجع.
الأخطاء الشائعة وإصلاحها
ERROR 1213 (40001): Deadlock found when trying to get lock
- لماذا يحدث؟
- أخذت معاملات متزامنة أقفالاً متعارضة في دائرة.
- كيف تصلحه؟
- تراجع وأعد العملية التجارية كاملة ضمن حد مع منع تكرار أثرها.
- كيف تتجنب تكراره؟
- وحد ترتيب الأقفال واستخدم فهارس مناسبة ومعاملات قصيرة.
ERROR 1205: Lock wait timeout exceeded
- لماذا يحدث؟
- بقي قفل مطلوب محجوزاً بعد مدة الانتظار.
- كيف تصلحه؟
- أنه المعاملة الفاشلة وافحص المسبب وقرر إعادة المحاولة.
- كيف تتجنب تكراره؟
- راقب عمر المعاملة وتجنب انتظار المستخدم داخلها.
لا يعكس ROLLBACK عبارة ALTER TABLE
- لماذا يحدث؟
- لتعريف البيانات سلوك حفظ ضمني خارج تراجع التغييرات العادية.
- كيف تصلحه؟
- استخدم ترحيل مخطط واستراتيجية تعافٍ مراجعين.
- كيف تتجنب تكراره؟
- افصل تغيير المخطط عن الاستدلال على معاملة العمل.
اختبر فهمك
1. تقفل A الحساب 10 ثم 20، وتقفل B الحساب 20 ثم 10. فسر الفشل وأعد التصميم.
اعرض الحل المشروح
قد تمسك كل جلسة قفلها الأول وتنتظر الآخر فتتكون دائرة. اجعل المعاملتين تقفلان المفاتيح بترتيب واحد واختصر العمل واحتفظ بإعادة كاملة محدودة؛ فقد تنشأ تعارضات أخرى. يقلل الترتيب الموحد التعارضات لكنه لا يثبت غيابها في كل حمل.
2. تظهر قراءتان عاديتان في REPEATABLE READ الرصيد القديم بعد حفظ تحديث من جلسة أخرى. هل تعطلت المزامنة بالضرورة؟
اعرض الحل المشروح
لا؛ قد تنتمي القراءتان إلى لقطة واحدة على الخادم نفسه. حدد حدود المعاملة والعزل ونقطة الاتصال أولاً. أنهِ المعاملة وافحص رؤية محفوظة جديدة في المختبر. استخدم قراءة مقفلة لقرار تغيير آني عند ملاءمتها بدلاً من خفض العزل العام لإخفاء سوء فهم اللقطة.
أهم ما تعلمته
- تجيب الذرية والعزل والمتانة عن أسئلة مختلفة.
- تتطلب التعارضات إعادة محاولة مدروسة وإنهاءً صريحاً للمعاملة.