MySQL وتصميم قواعد البيانات

فهم المعاملات

13 دقيقة الدرس 26 من 40

فهم المعاملات

المعاملات هي واحدة من أهم المفاهيم في إدارة قواعد البيانات. تتيح لك تجميع عمليات SQL متعددة في وحدة عمل واحدة ذرية إما أن تنجح تماماً أو تفشل تماماً، مما يضمن اتساق البيانات والموثوقية.

ما هي المعاملات؟

المعاملة هي تسلسل من عملية واحدة أو أكثر من عمليات SQL التي تُعامل كوحدة واحدة. فكر في الأمر مثل تحويل مصرفي: إذا قمت بسحب الأموال من حساب واحد، يجب إيداعها في حساب آخر. يجب أن تنجح كلتا العمليتين، أو لا ينبغي أن يحدث أي منهما.

مثال من الواقع: عندما تشتري منتجاً عبر الإنترنت، تحدث عمليات قاعدة بيانات متعددة: تقليل المخزون، إنشاء سجل طلب، تحصيل الدفع، وتحديث سجل العميل. يجب أن تنجح كل هذه العمليات معاً، أو يجب عكس العملية بأكملها.

خصائص ACID

تضمن المعاملات أربع خصائص أساسية، تُعرف باختصار ACID:

A - Atomicity (الذرية): إما أن تكتمل جميع العمليات أو لا شيء C - Consistency (الاتساق): تنتقل قاعدة البيانات من حالة صالحة إلى أخرى I - Isolation (العزل): المعاملات المتزامنة لا تتداخل مع بعضها D - Durability (المتانة): بمجرد التنفيذ، تكون التغييرات دائمة (حتى بعد فشل النظام)

الذرية في العمل

تضمن الذرية أن المعاملات هي "الكل أو لا شيء". إذا فشل أي جزء، يتم التراجع عن كل شيء:

START TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; COMMIT;

إذا فشل الـ UPDATE الثاني (مثلاً، الحساب 2 غير موجود)، يتم التراجع عن الـ UPDATE الأول أيضاً، مع الحفاظ على اتساق البيانات.

الاتساق

يضمن الاتساق الحفاظ على جميع القيود والقواعد في قاعدة البيانات:

-- هذا الجدول لديه قيد CHECK: balance >= 0 START TRANSACTION; UPDATE accounts SET balance = balance - 500 WHERE account_id = 1; -- إذا كان هذا سيجعل الرصيد سالباً، تفشل المعاملة COMMIT;
مهم: يفرض MySQL الاتساق من خلال القيود والمحفزات والمفاتيح الخارجية. ستفشل المعاملة إذا انتهكت أياً من هذه القواعد.

أوامر التحكم في المعاملات

توفر MySQL ثلاثة أوامر رئيسية للتحكم في المعاملات:

START TRANSACTION; -- بدء معاملة جديدة COMMIT; -- حفظ جميع التغييرات بشكل دائم ROLLBACK; -- التراجع عن جميع التغييرات منذ START TRANSACTION

مثال معاملة أساسي

إليك مثال كامل لتحويل الأموال بين حسابين مصرفيين:

START TRANSACTION; -- الخطوة 1: خصم من حساب المرسل UPDATE accounts SET balance = balance - 500.00, updated_at = NOW() WHERE account_id = 101; -- الخطوة 2: إضافة إلى حساب المستقبل UPDATE accounts SET balance = balance + 500.00, updated_at = NOW() WHERE account_id = 202; -- الخطوة 3: تسجيل المعاملة INSERT INTO transaction_log (from_account, to_account, amount, transaction_date) VALUES (101, 202, 500.00, NOW()); -- إذا نجح كل شيء، قم بالتنفيذ COMMIT;

معالجة الأخطاء باستخدام ROLLBACK

عندما يحدث خطأ ما، استخدم ROLLBACK للتراجع عن التغييرات:

START TRANSACTION; UPDATE products SET stock = stock - 5 WHERE product_id = 123; -- تحقق إذا أصبح المخزون سالباً SELECT stock FROM products WHERE product_id = 123; -- إذا كان المخزون < 0، تراجع عن التغيير ROLLBACK; -- وإلا، احفظ التغيير -- COMMIT;
أفضل ممارسة: قم دائماً بتضمين معالجة الأخطاء في كود تطبيقك. إذا فشلت أي عملية في المعاملة، قم بتنفيذ ROLLBACK على الفور للحفاظ على سلامة البيانات.

وضع الالتزام التلقائي (Autocommit)

بشكل افتراضي، يعمل MySQL في وضع الالتزام التلقائي، حيث يتم الالتزام تلقائياً بكل عبارة SQL:

-- تحقق من حالة autocommit SELECT @@autocommit; -- يرجع 1 (مفعّل) أو 0 (معطّل) -- تعطيل autocommit SET autocommit = 0; -- الآن العبارات لا يتم الالتزام بها حتى تقوم بتنفيذ COMMIT صراحة UPDATE accounts SET balance = balance + 100 WHERE account_id = 1; COMMIT; -- إعادة تفعيل autocommit SET autocommit = 1;
تحذير: عندما يكون autocommit معطلاً، يجب أن تتذكر تنفيذ COMMIT للتغييرات. تُفقد التغييرات غير الملتزم بها إذا تم إغلاق الاتصال أو إعادة تشغيل الخادم.

نقاط الحفظ (Savepoints)

تتيح لك نقاط الحفظ إنشاء نقاط تفتيش داخل المعاملة يمكنك التراجع إليها:

START TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE account_id = 1; SAVEPOINT after_withdrawal; UPDATE accounts SET balance = balance + 100 WHERE account_id = 2; -- إذا حدث خطأ ما مع الإيداع، تراجع إلى نقطة الحفظ ROLLBACK TO SAVEPOINT after_withdrawal; -- أو التزم بكل شيء COMMIT;

متى تستخدم المعاملات

استخدم المعاملات عندما:

  • يجب أن تنجح تغييرات متعددة مرتبطة معاً - طلبات التجارة الإلكترونية، التحويلات المالية
  • سلامة البيانات أمر بالغ الأهمية - البنوك، السجلات الطبية، إدارة المخزون
  • المنطق التجاري المعقد يتطلب عمليات ذرية - عمليات متعددة الخطوات
  • قد يتعارض المستخدمون المتزامنون - أنظمة الحجز، مبيعات التذاكر

مثال من الواقع: طلب تجارة إلكترونية

إليك معاملة كاملة للتجارة الإلكترونية تتعامل مع تقديم الطلب:

START TRANSACTION; -- 1. إنشاء الطلب INSERT INTO orders (customer_id, order_date, total_amount, status) VALUES (456, NOW(), 149.99, 'pending'); SET @order_id = LAST_INSERT_ID(); -- 2. إضافة عناصر الطلب INSERT INTO order_items (order_id, product_id, quantity, price) VALUES (@order_id, 101, 2, 49.99), (@order_id, 205, 1, 49.99); -- 3. تقليل المخزون UPDATE products SET stock = stock - 2 WHERE product_id = 101; UPDATE products SET stock = stock - 1 WHERE product_id = 205; -- 4. تحقق إذا أصبح أي مخزون سالباً SELECT MIN(stock) INTO @min_stock FROM products WHERE product_id IN (101, 205); IF @min_stock < 0 THEN ROLLBACK; SELECT 'فشل الطلب: مخزون غير كافٍ' AS message; ELSE COMMIT; SELECT 'تم تقديم الطلب بنجاح' AS message, @order_id AS order_id; END IF;

اعتبارات أداء المعاملات

اجعل المعاملات قصيرة: المعاملات الطويلة تقفل الموارد قلل العمل داخل المعاملات: لا تضمّن استدعاءات API خارجية استخدم مستويات العزل المناسبة: وازن بين الاتساق والأداء تعامل مع الجمود: نفذ منطق إعادة المحاولة في كود التطبيق راقب حجم سجل المعاملات: المعاملات الكبيرة يمكن أن تملأ السجلات

تمرين عملي:

السيناريو: أنشئ معاملة لنظام استعارة كتب المكتبة.

المتطلبات:

  1. تحديث available_copies للكتاب (تقليل بمقدار 1)
  2. إدراج سجل استعارة مع member_id و book_id و checkout_date
  3. تحديث عدد books_checked_out للعضو (زيادة بمقدار 1)
  4. تحقق إذا تجاوز books_checked_out الحد (5 كتب)
  5. إذا تجاوز الحد، تراجع؛ وإلا التزم

الحل:

START TRANSACTION; -- تحديث توفر الكتاب UPDATE books SET available_copies = available_copies - 1 WHERE book_id = 789; -- إنشاء سجل استعارة INSERT INTO checkouts (member_id, book_id, checkout_date, due_date) VALUES (123, 789, NOW(), DATE_ADD(NOW(), INTERVAL 14 DAY)); -- تحديث عدد استعارات العضو UPDATE members SET books_checked_out = books_checked_out + 1 WHERE member_id = 123; -- تحقق من الحد SELECT books_checked_out INTO @count FROM members WHERE member_id = 123; -- تحقق من توفر الكتاب SELECT available_copies INTO @available FROM books WHERE book_id = 789; -- التحقق من الشروط IF @count > 5 OR @available < 0 THEN ROLLBACK; SELECT 'فشلت الاستعارة: تجاوز الحد أو الكتاب غير متوفر'; ELSE COMMIT; SELECT 'تمت استعارة الكتاب بنجاح'; END IF;

الملخص

في هذا الدرس، تعلمت:

  • المعاملات هي وحدات عمل ذرية تضمن اتساق البيانات
  • خصائص ACID تضمن معالجة المعاملات الموثوقة
  • استخدم START TRANSACTION و COMMIT و ROLLBACK للتحكم في المعاملات
  • وضع Autocommit يؤثر على كيفية الالتزام بالعبارات
  • نقاط الحفظ توفر نقاط تفتيش داخل المعاملات
  • المعاملات ضرورية للعمليات المعقدة متعددة الخطوات
التالي: في الدرس التالي، سنستكشف مستويات عزل المعاملات وكيف تتفاعل المعاملات المتزامنة مع بعضها البعض!