SQLتنفيذ كل الأوامر أو إلغاءها كلها
- مفهوم الـ Transaction
- تجهيز قاعدة البيانات التي سنطبق عليها
- طريقة وضع الكود بداخل Transaction
- التراجع عن تنفيذ أوامر الـ Transaction
مفهوم الـ Transaction
Transaction يقصد بها مجموعة من الأوامر إما أن تتنفذ جميعها بنجاح أو لا يتم تنفيذها.
هناك حالات كثيرة تكون فيها مضطر إلى تنفيذ مجموعة أوامر أو التراجع عن تنفيذها خاصةً إذا كنت تطور قاعدة بيانات لمشروع فيه معاملات مالية.
فمثلاً إذا كنت تنوي شراء برنامج من أي موقع إلكتروني، في هذه الحالة سيطلب منك الموقع إدخال معلومات بطاقتك المصرفية التي ستدفع من خلالها، بعد أن تدخل معلومات البطاقة، سيتم التأكد من أنك تملك المال المطلوب في البطاقة، إذا كنت تملك ثمن شراء البرنامج في بطاقتك، سيقوم الموقع بتسجيل أنه تم بيع نسخة من البرنامج لك، و ستجد أن الموقع أرسل لك كود تفعيل للبرنامج خاص بك، و ستجد أن بطاقتك المصرفية تم إقتطاع المبلغ الذي دفعته منها.
في حالة الشراء أونلاين قد تقع في مشاكل كارثية ما لم يتم تنفيذ جميع الخطوات بنجاح. فمثلاً في حال قمت بتحويل المال للموقع الإلكتروني و فجأةً تعطل الموقع قبل أن يسجل في قاعدة البيانات أنك قمت بشراء نسخة البرنامج و قبل أن يرسل لك كود تفعيل البرنامج الذي دفعت ثمنه فإنك ستخسر مالك.
Transaction تعني محاولة تنفيذ جميع الأوامر و في حال فشل أي أمر موضوع يجب إلغاء تنفيذ كل الأوامر التي تم تنفيذها بنجاح.
قواعد بيانات MySQL - SQL Server - Access - Oracle - SQLite جميعها تتيح لك إمكانية وضع الكود في Transaction و لكن أسلوب كتابتها تختلف قليلاً من قاعدة بيانات لأخرى.
تجهيز قاعدة البيانات التي سنطبق عليها
قم بتنفيذ الإستعلام التالي حتى تنشئ قاعدة بيانات جديدة إسمها harmash
و تنشئ فيها الجداول التالية:
users
جدول خاص لحفظ معلومات المستخدمين و قد وضعنا فيه بيانات 3 مستخدمين.products
جدول خاص لحفظ معلومات المنتجات و قد وضعنا فيه بيانات 5 منتجات.orders
جدول خاص لحفظ الطلبيات.
مثال
فيما يلي البيانات التي قمنا بإضافتها في الجدول users
.
users | ||
---|---|---|
id | username | |
1 | Mhamad | mhamad@example.com |
2 | Hala | mhamad@example.com |
3 | Sarah | mhamad@example.com |
فيما يلي البيانات التي قمنا بإضافتها في الجدول products
.
products | ||
---|---|---|
id | title | available |
1 | Mouse | 86 |
2 | Keyboard | 140 |
3 | Printer | 45 |
4 | Screen | 32 |
5 | Chair | 80 |
فيما يلي البيانات التي قمنا بإضافتها في الجدول orders
.
orders | |||
---|---|---|---|
user_id | product_id | quantity | sale_date |
طريقة وضع الكود بداخل Transaction
في قواعد بيانات MySQL يجب أولاً إعلام قاعدة البيانات بأنك تريد إيقاف الحفظ التلقائي و هذه الخطوة تحتاج أن تفعلها مرة واحدة فقط و ليس عند إرسال كل إستعلام.
لإعلام قاعدة البيانات بأنك تريد إيقاف الحفظ التلقائي، يجب أن تنفذ الإستعلام التالي.
أسلوب قواعد بيانات MySQL / Oracle / SQLite
أسلوب قواعد بيانات SQL Server / ACCESS
خطوات بناء Transaction
- نضع الأمر BEGIN أو BEGIN TRANSACTION على حسب نوع قاعدة البيانات التي نستخدمها.
- نضع الأوامر التي نريدها إما أن تتنفذ جميعها بنجاح و إما لا يتم تنفيذها.
- نضع الأمر COMMIT لحفظ جميع التغييرات إذا تم تنفيذ جميع الأوامر بنجاح.
في الإستعلام التالي إفترضنا أننا نقوم بتخزين عملية شراء لمنتج.
- المنتج الذي تم بيعه إفترضنا أنه يملك
id
يساوي4
. - الشخص الذي قام بشراء المنتج إفترضنا أنه يملك
id
يساوي1
.
إذا تمت عملية البيع بنجاح، يجب إنقاص كمية المنتج الذي تم بيعه في جدول المنتجات products
.
أيضاً، يجب إضافة id
الشخص الذي قام بالشراء و id
المنتج الذي تم بيعه في جدول الطلبيات orders
.
بما أنه يجب تنفيذ العمليتين سويةً أو عدم تنفيذهما من الأساس في حال حدث خطأ ما، سنقوم بوضع العملية بداخل Transaction.
مثال
النتيجة
1 row(s) inserted
1 row(s) affected
0 row(s) affected
النتيجة تعني أنه تم تنفيذ الأوامر BEGIN و INSERT و UPDATE و COMMIT بنجاح.
إذا قمت بعرض بيانات الجدول products
ستلاحظ أنه تم تحديث قيمة الحقل quantity
حيث كانت 86 ثم أصبحت 76.
products | ||
---|---|---|
id | title | available |
1 | Mouse | 76 |
2 | Keyboard | 140 |
3 | Printer | 45 |
4 | Screen | 32 |
5 | Chair | 80 |
و إذا قمت بعرض بيانات الجدول orders
ستلاحظ أنه تم إضافة سطر جديد فيه كما يلي.
orders | |||
---|---|---|---|
user_id | product_id | quantity | sale_date |
1 | 4 | 10 | 2024-07-11 |
التراجع عن تنفيذ أوامر الـ Transaction
لحفظ كل التغيرات التي تم إجراءها بداخل Transaction قلنا أنه يجب تنفيذ الأمر COMMIT.
الآن للتراجع عن كل التغيرات التي تم إجراءها في قاعدة البيانات (أي لعدم حفظها)، يمكن تنفيذ الأمر ROLLBACK ما لم يتم تنفيذ الأمر COMMIT بعد لأنه لا يمكننا التراجع عن تنفيذ الأوامر في حال سبق و تم حفظها.
في الإستعلام التالي إفترضنا أننا نقوم بتخزين عملية شراء لمنتج و لكننا في النهاية قررنا إلغاء العملية.
- المنتج الذي تم بيعه إفترضنا أنه يملك
id
يساوي5
. - الشخص الذي قام بشراء المنتج إفترضنا أنه يملك
id
يساوي2
.
إذا تمت عملية البيع بنجاح، يجب إنقاص كمية المنتج الذي تم بيعه في جدول المنتجات products
.
أيضاً، يجب إضافة id
الشخص الذي قام بالشراء و id
المنتج الذي تم بيعه في جدول الطلبيات orders
.
بما أنه يجب تنفيذ العمليتين سويةً أو عدم تنفيذهما من الأساس في حال حدث خطأ ما، سنقوم بوضع العملية بداخل Transaction.
في النهاية، بما أننا سنقوم بإلغاء تنفيذ العمليتين فإننا سنستدعي الأمر ROLLBACK.
مثال
النتيجة
1 row(s) inserted
1 row(s) affected
0 row(s) affected
النتيجة تعني أنه تم تنفيذ الأوامر BEGIN و INSERT و UPDATE و ROLLBACK بنجاح.
إذا قمت بعرض بيانات الجدول products
ستلاحظ أنها لم تتغير.
products | ||
---|---|---|
id | title | available |
1 | Mouse | 76 |
2 | Keyboard | 140 |
3 | Printer | 45 |
4 | Screen | 32 |
5 | Chair | 80 |
و إذا قمت بعرض بيانات الجدول orders
ستلاحظ أنه لم تتغير أيضاُ.
orders | |||
---|---|---|---|
user_id | product_id | quantity | sale_date |
1 | 4 | 10 | 2024-07-11 |