- 0
سجل دخول لمتابعه هذا
متابعين
0

الشموع الموقَدات لكشف تضارب البيانات
بواسطة
الغملاسي,
-
يستعرض القسم حالياً 0 members
لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .
بواسطة
الغملاسي,
لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .
تم النشر منذ (معدل)
( الشموع الموقــَدات لكشف تضارب البيانات )
السلام عليكم
في هذه المقالة سنتطرق لموضوع تضارب البيانات concurrency violation الغير واضح المعالم.
لماذا؟ السبب أن الحلول متعددة بحيث تعتمد على وضع و وقت و كيفية التضارب.
ناهيك عن تعدد أنواع التضارب , لذلك أوقدنا الشموع لرؤية هذا التضارب عن كثب.
هنالك على حسب علمي المتوضع ثلاثة وضعيات أو استراتيجيات لهذه المشكلة وهي كالتالي:
أولاً ما يعرف بـ استراتيجية التضارب المشؤوم pessimistic concurrency strategy.
ثانياً: ما يعرف بـ استراتجية التضارب المحمود optimistic concurrency strategy .
ثالثاً: ما يعرف بـ استراتيجية الاخر هو الاولى Last in wins strategy .
لكن قبل كل ذلك, ينبغي علينا تعريف مالمقصود بـتضارب البيانات.
هي عملية تحدث بين مستخدمين أو أكثر بحيث يقومان بالعمل على نفس البيانات في نفس الوقت
هذه العملية كما تعلمون تعرف بـ concurrency violation
متى يقع التضارب ؟
تقع المشكلة عند عملية التحديث سواءً في الاضافة أو التعديل او الحذف, لكن ليس في عملية الاختيار Select Statement
إلا ان عملية الاختيار, كما سيأتينا لاحقاً انها كذلك لم تسلم من عملية تضارب البيانات. وإن كان البرنامج يعمل كما ينبغي.
إلا ان المعطيات ستكون غير صحيحة.
هنالك تفسير إيجابي للتضارب وهو :
Maximize the amount of work that can be done by all users at the same time, and most
importantly, make all users feel like they’re important
الاستراتيجية الاولى : استراتيجية التضارب المشؤوم pessimistic concurrency strategy.
الوضع : ان يكون فقط مستخدم واحد يُحدث في نفس الوقت, وهذا المستخدم غير مشروط
ربما يكون عمر في المرة الاولى ويكون زيد في المرة الثانية. من يجلب البيانات أول هو احق بالتحديث عن سواه.
الاستراتيجية الاولى تعتمد على غلق الحقل الذي هو قيد الاستخدام كتحديث حتى ينتهي منه المستخدم الحالي
ثم بعد ذلك يفتح هذا الحقل للمستخدم الاخر. لكن لن يتم اعتماد تحديث المستخدم الاخر, هذه العملية تعرف بـالتحديث
المفقود a lost update.
على سبيل المثال زيد وعمر قاما بجلب بيانات عامود الراتب الشهري,
وكان الصف الاول فيه القيمة 5000 درهم,
تم قفل الحقل لمصلحة زيد, زيد زاد على الصف الاول 1000 درهم
الان البيانات لن تصل إلى عمر, وعمر ما زال ينتظر عملية جلب البيانات,
ولن يفلح, حتى يفرغ زيدٌ منها, الان قام زيد بالتحديث فاصبحت 6000 درهم.
تم فتح القفل عن الحقل, الان وصلت البيانات إلى عمر 6000 درهم .
عمر قام بانقاص 2000 درهم لتصبح 4000 درهم , قام عمر بتحديث البيانات.
لم يقبل التحديث لان التحديث المقفول بزيد لا يمكن تخطيه بتحديث عمر الغير مقفل في بداية الامر
حتى وان كان عمر من حدث فيما بعد. السبب كما ذكرنا أن هذه العملية تضمن تحديث واحد فقط في الوقت نفسه.
لذلك يعرف تحديث عمر بالتحديث المفقود lost update و الراتب الشهري في النهاية هو 6000 درهم .
ملاحظة: بما أن الحل متعلق بقفل الحقل, فهو واضح انه لا يدعم تقنية الاتصال المنقطع Disconnected environment
الاستراتيجية الثانية : استراتجية التضارب المحمود optimistic concurrency strategy .
الوضع : ان يكون اعتماد التحديث للبيانات متزامن مع الطرفين.
الاستراتيجية الثانية لا تعتمد على غلق الحقل, انما تعتمد على من يحدث اولاً قبل الاخرين.
لنفترض ان مستخدمان قاما بجلب البيانات و كانت قيمة الصف , عبارة عن حجز تذكرة
وباقي من كراسي الغير محجوزة 5 كراسي , قام المستخدم الاول بإعتماد الحجز له فاصبحت
4 وبما ان الحقل غير مقفل اثناء عمل المستخدم الاول عليه,
استطاع المستخدم الثاني جلب البيانات وهي 5 الان المستخدم الاخر قام بحجز كرسي له فاصبحت 4
قام بالتحديث , تم قبول التحديث ,الان قام المستخدم الاول ليحدث نفس الحقل بالقيمة 4
تم رفض التحديث كون القيمة العائدة هي القيمة الحالية وهي 4 كراسي فقط
و كذلك قيمة الصف القديمة ليست مطابقة للقيمة الاصلية في قاعدة البيانات والتي كانت 5 كراسي .
في الاخير, تم اعتماد حجزي المستخدمان مع ان الكراسي المحجوزة هو كرسي واحد فقط
بمعنى اخر تم حجز كرسي لشخصين...
متى يحدث التضارب المحمود : يحدث عندما يجلب مستخدم قيمة ما ويقوم الاخر
بجلب نفس القيمة ثم يغيرها ويحدثها , ثم يقوم الاول بمحاولة تحديث القيمة
التي تغيرت بواسطة المستخدم الاخر , هنا تقع المشكلة أو ما يعرف بـ optimistic concurrency violation
لماذا : لانه شرط هذه التقنية أن شرط التحديث يعتمد على التحقق من البيانات المُحدثة الحالية Current
مع البيانات الاصلية في قاعدة البيانات Original Data .
ملاحظة: الـ Dataset مصصمة لأجل هذه التقنية وهي داعمة لها و تتبناها.
الاستراتيجية الثالثة : استراتيجية الاخر هو الاولى Last in wins strategy .
الوضع : هو أن من يحدث أخرًا لا يفقد تحديثه.
الحل الثالث : لا يعتمد على غلق الحقل, انما يعتمد على من يحدث اخرًا بعد الاخرين.
لنفترض ان مستخدمان قاما بجلب البيانات و كانت قيمة الصف , عبارة عن حجز تذكرة
وباقي من كراسي الغير محجوزة 5 كراسي , قام المستخدم الاول بإعتماد الحجز له فاصبحت
4 وبما ان الحقل غير مقفل اثناء عمل المستخدم الاول عليه,
استطاع المستخدم الثاني جلب البيانات وهي 5 الان المستخدم الاخر قام بحجز كرسي له فاصبحت 4
قام بالتحديث , تم قبول التحديث ,الان قام المستخدم الاول ليحدث نفس الحقل بالقيمة 4
تم قبول التحديث وتم فقد قيمة تحديث المستخدم الاول وهي 4 كراسي فقط
تم اعتماد حجز المستخدم الاخر ,مع ضياع قيمة تحديث المستخدم الاول.
لماذا: لاسبب بسيط أن هذه التقنية لا تعتمد على تدقيق تطابق البيانات المُحدثة
بالبيانات الاصلية في قاعدة البيانات.
ملاحظة: اعتماد شرطية المفتاح الاساسي أو وقت التحديث أو رقم الصف, هي احدى حلول هذه الوضعية.
الحلول المطروحة: لمشكلة التضارب المشؤوم pessimistic concurrency strategy.
الحلول كثيرة باستخدام احدى عوازل العنصر transaction المتوفرة في النسخة 2005
لنتعرف على هذه الحلول بالتعرف على العوازل و انوعها.
مستوى العزل isolation level
ماهو مستوى العزل : هو عزل عملية التحديث الكلي transaction عن تحديث كلي أخر transaction
هنالك ثلاثة عوائق عند عملية التحديث الكلي وهم كالتالي :
اولاً : القراءة القذرة Dirty Read
ثانياً : القراءة المتعجلة non repeatable Read
ثالثًا : القراءة الوهمية phantom Read
القراءة القذرة Dirty Read تحدث هذه القراءة عندما يقوم مستخدمان أو اكثر, بالتعامل مع بيانات تم
رفض تحديثها عن طريق عملية التراجع عن التحديث Roll back عبر مستخدم ثالث.
على سبيل المثال: قام المستخدم الاول بتحويل 100 درهم من أموال الحساب الجاري وهي 500 درهم
إلى حساب التوفير الذي ليس به شيء,ومع ان حساب الجاري مقفل إلا ان المستخدم الاخر استطاع أن
يجلب قيمة الحساب الحالية وهي بعد التحول اصبحت 400 درهم, قام المستخدم الاول بعملية التحديث
إلا أن التحديث قد فشل , لسببٍ ما , على سبيل المثال حساب التوفير أغلق.. الان تمت عملية
التراجع Roll back أُعيدت المئة درهم لحساب الجاري و تم فتح القفل, لكن لازال المستخدم
الاخر يتعامل مع الراتب على اساس 400 درهم, لذلك هذا المنطق يعرف بالقراءة القذرة.
القراءة المتعجلة nonrepeatable Read تحدث عندما نقوم بقراءة بيانات تم تحديثها اثناء قرائتنا لها.
على سبيل المثال: قام المستخدم الاول بتشغيل تقرير الرواتب وكان حينها 1000 درهم للموظف الاول
في نفس الوقت كان مستخدم اخر يستخدم الحقول نفسها , حيث قام بزيادة راتب الموظف بـ 500 درهم
فبينما يفترض أن يكون راتب الموظف الاول هو 1500 درهم
إلا ان التقرير كان يعرض الراتب على اساس 1000 درهم فقط, لذلك يعرف هذا المنطق بالقراءة المتعجلة.
القراءة الوهمية phantom Read تحدث عندما نقوم بقراءة بيانات تم أضافة بيانات أخرى معها ولم ندركها.
على سبيل المثال: قام المستخدم الاول بتشغيل تقرير الرواتب وكان حينها 1000 درهم للموظف الاول
في نفس الوقت كان مستخدم اخر يستخدم الحقول نفسها , حيث قام بأضافة علاوة بدل الزوجية
بمبلغ 500 درهم , وبما أن العلاوة لم تكون حاضرة وقت تحميل التقرير
فهي قيمة مجهولة للمستخدم الاول , لذلك كان يفترض أن يكون المجموع في التقرير 1500 درهم
إلا ان التقرير كان يعرض الراتب على اساس 1000 درهم فقط, لذلك يعرف هذا المنطق بالقراءة الواهمة.
اي القراءة الغير صحيحة أو القراءة الظالمة.
الخيارات المتوفرة في مستوى العزل في SQL Server 2005
Chaos هذا الخيار غير مدعم في الـ SQLClient, ومدعم عبر الـ ADO.NET بشكل عام,
مثلاً في ADODB يعرف بـ adXactChaos , وهو عازل عنيد لايسمح بالكتابة على البيانات التي يتعامل معها.
ReadUncommitted هذا الخيار هو أقل مستوى للعزل (حيث تنطبق عليه المعوقات كلها)
وهو واضح من اسمه انه يقرء حتى القيمة التي لم تكون في الوضع Committed .
ReadCommitted: هذا الخيار الافتراضي ينتظر القيمة التي في وضع التعديل, حتى تصبح Committed
فيكمل المهمة أو يقوم بالتراجع. هذا الخيار لا يستطيع أن يعدل ما يتم تعديله من عنصر أخر,
بينما العناصر الاخرى تستطيع تعديل ما يعدله هذا الـ transaction
هذا العنصر يستخدم Row Versioning كإحدى الثوابت التي يعول عليها في عملياته.
الـ Row Version هو عبارة عن صف ينشأ في قاعدة البيانات tempdb كنوع من
الثوابت لمعرفة اخر حاله للصف قبل التعديل. يتم ذلك عبر specific transaction عنصر خاص يقوم
بعملية الربط بـ Link List بحيث تسند قيمة الصف في قاعدة البيانات الاصلية
بينما تسند نسخة الصف Version في قاعدة البيانات tempdb .
كذلك يستخدم الاقفال المشتركة shared locks لمنع القراءات القذرة ,لكن البيانات
يمكن تغيرها قبل ان ينتهي هو من مهامه , لذلك القراءة المتعجلة و الوهمية nonrepeatable & phantom reads,
احتمالية حدوثها واردة لا محالة.
ملاحظة: لإستخدام هذا النوع من العزل على قاعدة البيانات المعنية, نفذ هذا الكود.READ_COMMITTED_SNAPSHOT
RepeatableRead: هذا الخيار لا يستطيع أن يعدل قيمة لم يحن إعتمادها ولا يستطيع عنصر
اخر ان يعدل ما يتم تعديله في هذا العنصر الحالي, حتى ينتهي منها ويتم اعتمادها Committed .
هذا العنصر يستخدم الاقفال المشتركة shared locks وهذا يعني حماية البيانات المستخدمة من اي
طرف اخر, إلا للقراءة فقط, لكن المشكلة أنه يسمح كذلك بإضافة صفوف جديدة,
مما يسهم في مشكلة القراءة الوهمية Read phantom .
:Serializable هذا الخيار هو أعلى مستوى للعزل (حيث لا تنطبق عليه المعوقات كلها)
يُمنع هذا العزل من قراءة بيانات تستخدم من قبل الاخرين, وكذلك يمنع اي عنصر خارجي باستخدام
ما هو قيد التعديل عنده.حتى الاضافة يمنعها فلا يسمح بإخال صف جديد ضمن الصفوف التي لديه
حتى ينتهي منها. فهو عازل صارم للغاية.
Snapshot هذا الخيار يستخدم نسخة الصف كذلك Row Versioning في بدء عملياته,
هذا الخيار تُحجب عنه الصفوف التي يتم التعديل عليها من اطراف اخرى,فهو يرى فقط البيانات
التي لم تمس من قبل الاخرين. وهو لا يتطلب قفل الصفوف عند عملية القراءة ,إلا أنه يستخدمه
في عملية التراجع عن التعديل Rolled Back .
ملاحظة: لإستخدام هذا النوع من العزل على قاعدة البيانات المعنية , نفذ هذا الكود.
Unspecified غير محدد.
ملاحظة : العوازل الـ 6 مدعمة جميعها في الـ Compact framework
نصائح في استخدام العزل المناسب للمشاريع
العزل ReadUncommitted يفضل في المشاريع التي يتم التعامل مع البيانات بشكل سريع وفي اقصر وقت.
العزل RepeatableRead يفضل في المشاريع التي تتطلب دقة كاملة في تشغيل التحديثات التامة , مع ضمان منع
اي تحديث من اطراف اخرى, حتى ينته الحالي من عمليته الحالية.
العزل Serializable يفضل في المشاريع التي تتطلب دقة تامة عند التعامل مع البيانات , بحيث تمنع حتى عملية
الادخال من اطراف اخرى , حتى ينتهي الـ transaction من عمليته .
العزل Snapshot يفضل في المشاريع التي تستخدم محاسبات معقدة و لغرض القراءة فقط.
في الاخير وبلا ادنى شك أن هذا الفتات لا يغطي حقيقة تقنية العزل, إلا ان المقالة جرتنا للخوض فيه.
شاهد النصوص البرمجية لذلك.
الحلول المطروحة: لمشكلة التضارب المحمود optimistic concurrency strategy.
الحل الاول : استخدام الحدث RowUpdated Event التابعة للـ DataAdpater بهي نستطيع أن
نعرف هل حدث التصادم أم لا و ببعض خصائصه نتحكم بالخطأ الذي صدر من صفٍ ما .
الحل الثاني: هو تمكين الخاصية ContinueUpdateOnError بحيث تساوي True لتكملة التحديث حتى وان كان
هنالك خطأٌ ما في صفٍ ما, بحيث يقوم بتخطي الخطأ دون تحديثه, مع استمرار تحديث الصفوف التي بعده.
هذه الخاصية : تمنع إنهيار أو تجمد البرنامج , وكذلك تمنع رسالة الخطأ الافتراضية .
الخاصية ContinueUpdateOnError هي احدى خواص الـ DataAdapter .
ثالثاً : يمكنك امساك التضارب عبر القالب
DBConcurrencyException
شاهد النصوص البرمجية لعمل ذلك.
نكتب هذا الكود في صفحة الـ DataSet.vb
Handling_Database_Operation_Conflicts.rar
تم تعديل بواسطه الشهاب الحارقشارك هذا الرد
رابط المشاركة
شارك الرد من خلال المواقع ادناه