SQL تنفيذ كل الأوامر أو إلغاءها كلها

مفهوم الـ Transaction

كلمة Transaction يقصد بها مجموعة من الأوامر إما أن تتنفذ جميعها بنجاح و إما لا يتم تنفيذها.

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

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

كخلاصة للموضوع, Transaction يقصد بها محاولة تنفيذ جميع الأوامر و في حال فشل أي أمر موضوع موضوع يجب إلغاء تنفيذ كل الأوامر التي تم تنفيذها بنجاح.
قواعد بيانات MySQL - SQL Server - Access - Oracle - SQLite جميعها تتيح لك إمكانية وضع الكود في Transaction.

طريقة وضع الكود بداخل Transaction

في البداية, إذا كنت تتعامل مع قواعد بيانات MySQL يجب أولاً إعلام قاعدة البيانات بأنك تريد إيقاف الحفظ التلقائي و هذه الخطوة تحتاج أن تفعلها مرة واحدة فقط و ليس عند إرسال كل إستعلام.

لإعلام قاعدة البيانات بأنك تريد إيقاف الحفظ التلقائي, يجب أن تنفذ الإستعلام التالي.

SET autocommit = OFF;
	


الآن, عليك معرفة أن طريقة وضع الكود بداخل Transaction تختلف قليلاً من قاعدة بيانات لأخرى و لكن الفكرة هي نفسها تماماً.


في قواعد بيانات MySQL / Oracle / SQLite

BEGIN;
	-- statements
COMMIT;
	

  • الكلمة BEGIN نضعها لتحديد أين تبدأ الـ Transaction.
  • مكان الكلمة -- statements نضع كل الأوامر التي نريدها إما أن تتنفذ جميعها بنجاح و إما لا يتم تنفيذها.
  • الكلمة COMMIT نضعها لتحديد أين تنتهي الـ Transaction مما يعني أنه عند الوصول لها بدون أي مشاكل سيتم الموافقة على حفظ كل العمليات التي تم إجراءها.

ملاحظة

إذا كنت تستخدم قواعد بيانات SQL Server أو Access فكل ما عليك فعله هو تبديل كلمة BEGIN; بكلمة BEGIN TRANSACTION;.


مثال

في الإستعلام التالي, إفترضنا أننا نقوم بتخزين عملية شراء لمنتج.

  • المنتج الذي تم بيعه إفترضنا أنه يملك id يساوي 33.
  • الشخص الذي قام بشراء المنتج إفترضنا أنه يملك يملك id يساوي 1.

إذا تمت عملية البيع بنجاح, يجب إنقاص كمية المنتج الذي تم بيعه في جدول المنتجات products واحداً.
أيضاً, يجب إضافة id الشخص الذي قام بالشراء و id المنتج الذي تم بيعه في جدول الطلبيات orders.

بما أنه يجب تنفيذ العمليتين سويةً أو عدم تنفيذهما من الأساس في حال حدث خطأ ما, سنقوم بوضع العملية بداخل Transaction.

الإستعلام

-- Transaction هنا قمنا ببدء
BEGIN;
	
	-- يساوي 33 بهدف إنقاصها واحداً id للمنتج الذي يملك available_quantity هنا إفترضنا أننا نريد تحديث قيمة الحقل
	UPDATE products SET available_quantity = 9 WHERE id = 33;
	
	-- المنتج في جدول الطلبيات id المشتري و id سيتم إضافة أن available_quantity إذا لم يحدث مشكلة عند محاولة إنقاص 1 من قيمة الحقل
	INSERT INTO orders (user_id, product_id) values (1, 33);
	
-- سيتم حفظ التغيرات في قاعدة البيانات Transaction إذا لم يحدث أي خطأ في الأوامر الموضوعة في الـ
COMMIT;
		

التراجع عن تنفيذ أوامر الـ Transaction

لحفظ كل التغيرات التي تم إجراءها بداخل Transaction قلنا أننا يجب أن ننفذ الأمر COMMIT; لإعلام قاعدة البيانات أننا نريد حفظ كل العمليات التي تم إجراءها.
الآن للتراجع عن كل التغيرات التي تم إجراءها على قاعدة البيانات, يمكننا أن ننفذ الأمر ROLLBACK; ما لم يتم تنفيذ الأمر COMMIT; لأنه لا يمكننا التراجع عن تنفيذ الأوامر في حال تم تنفيذها.


مثال

في الإستعلام التالي, إفترضنا أننا نقوم بتخزين عملية شراء لمنتج و لكننا في النهاية قررنا إلغاء العملية.

  • المنتج الذي تم بيعه إفترضنا أنه يملك id يساوي 33.
  • الشخص الذي قام بشراء المنتج إفترضنا أنه يملك يملك id يساوي 1.

إذا تمت عملية البيع بنجاح, يجب إنقاص كمية المنتج الذي تم بيعه في جدول المنتجات products واحداً.
أيضاً, يجب إضافة id الشخص الذي قام بالشراء و id المنتج الذي تم بيعه في جدول الطلبيات orders.

بما أنه يجب تنفيذ العمليتين سويةً أو عدم تنفيذهما من الأساس في حال حدث خطأ ما, سنقوم بوضع العملية بداخل Transaction.
في النهاية, بما أننا سنقوم بإلغاء تنفيذ العمليتين في النهاية, سنستدعي الأمر ROLLBACK; بدل استدعاء الأمر COMMIT;.

الإستعلام

-- Transaction هنا قمنا ببدء
BEGIN;
	
	-- يساوي 33 بهدف إنقاصها واحداً id للمنتج الذي يملك available_quantity هنا إفترضنا أننا نريد تحديث قيمة الحقل
	UPDATE products SET available_quantity = 9 WHERE id = 33;
	
	-- المنتج في جدول الطلبيات id المشتري و id سيتم إضافة أن available_quantity إذا لم يحدث مشكلة عند محاولة إنقاص 1 من قيمة الحقل
	INSERT INTO orders (user_id, product_id) values (1, 33);
	
-- INSERT و UPDATE للتراجع عن تنفيذ الأمرين ROLLBACK هنا قمنا باستدعاء الأمر
ROLLBACK;
		

الدورات

أدوات مساعدة

الأقسام

دورات
مقالات أسئلة مشاريع كتب