القفل للتعامل مع التزامن – هل هو فكرة جيدة؟[مغلق]

StackOverflow https://stackoverflow.com/questions/225625

  •  03-07-2019
  •  | 
  •  

سؤال

من أجل التعامل مع مشكلة التزامن، هل يعتبر القفل - أي شكل من أشكال القفل، سواء كان قفل الصف أو الجدول أو قاعدة البيانات حلاً جيدًا؟

إذا لم يكن الأمر كذلك، كيفية التعامل مع مشكلة التزامن؟

هل كانت مفيدة؟

المحلول

إذا كنت تصدق أوراكل، لا، على الإطلاق.وذلك لأن شركة Oracle بذلت جهودًا كبيرة لتجنب ذلك.

المشكلة هي أن القراء يمكنهم حظر الكتّاب والكتاب يمنعون القراء، ويجب على الكاتب الانتظار حتى ينتهي جميع القراء من الصف قبل أن يتمكن من الكتابة.مما يؤخر عملية الكتابة والمتصل بها.يتم الاحتفاظ بالأقفال الحصرية (للكتابة) حتى نهاية المعاملة، في حالة ضرورة التراجع عن المعاملة - وهذا يمنع المعاملات الأخرى من رؤية القيمة الجديدة حتى يتم تنفيذ المعاملة.

في الممارسة العملية، يعد القفل أمرًا جيدًا بشكل عام إذا لم يكن هناك الكثير من التنافس، كما هو الحال مع أي برمجة متزامنة.إذا كان هناك الكثير من التنافس على صف/صفحة/جدول (لا تقوم العديد من خوادم قواعد البيانات بتأمين قاعدة البيانات بالكامل)، فسيؤدي ذلك إلى تنفيذ المعاملات بدورها وليس بشكل متزامن.

تستخدم Oracle تحديد إصدار الصف، حيث بدلاً من قفل الصف لكتابته، يتم إنشاء إصدار جديد من الصف بدلاً من ذلك.يتذكر القراء الذين يحتاجون إلى تكرار قراءاتهم إصدار الصف الذي قرأوه.ومع ذلك، سيحدث خطأ إذا حاول القارئ الذي يتذكر قراءاته تحديث صف تم تحديثه بواسطة كاتب آخر منذ أن قرأته هذه المعاملة؛هذا لوقف التحديثات المفقودة.للتأكد من أنه يمكنك تحديث صف ما، عليك أن تقول أن التحديد مخصص للتحديث؛إذا قمت بذلك، فسيتطلب الأمر قفلًا - يمكن لمعاملة واحدة فقط الاحتفاظ بصف للتحديث في كل مرة، ويجب انتظار المعاملة المتعارضة.

يدعم SQL Server 2005 والإصدارات الأحدث عزل اللقطات، وهو الاسم الخاص بهم لإصدار الصفوف.مرة أخرى، يجب أن تطلب أقفال التحديث إذا كنت بحاجة إلى تحديث بعض البيانات التي قرأتها للتو - في SQL Server، استخدم مع (UPDLOCK).

هناك مشكلة أخرى تتعلق بالقفل وهي احتمالية حدوث حالة توقف تام.هذا هو ببساطة حيث تحتفظ كل معاملة بقفل على مورد يحتاجه الآخر، أو بشكل عام، تحتوي دورة من المعاملات على أقفال يحتاج كل منها إلى التقدم.سيكتشف خادم قاعدة البيانات عمومًا هذا الجمود وينهي إحدى المعاملات، ويعيدها مرة أخرى - ستحتاج بعد ذلك إلى إعادة محاولة العملية.أي موقف يكون لديك فيه عدة معاملات متزامنة تقوم بتعديل نفس الصفوف من المحتمل أن يؤدي إلى حالة توقف تام.سيحدث حالة توقف تام إذا تم لمس الصفوف بترتيب مختلف؛من الصعب جدًا فرض الترتيب الذي سيستخدمه خادم قاعدة البيانات (عمومًا، تريد أن يختار المُحسِّن الترتيب الأسرع، والذي لن يكون بالضرورة متسقًا عبر الاستعلامات المختلفة).

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

نصائح أخرى

عليك أولاً أن تحدد هدفك.في حالة الطلب المتزامن هل ترغب في الفوز بالمستخدم الأخير أم المستخدم الأول.من المؤكد أن قفل قاعدة البيانات طريقة سيئة.حاول قفل الجدول/الصفوف في وقت متأخر قدر الإمكان ثم قم بتحرير القفل في أسرع وقت ممكن.

يعد تأمين قاعدة البيانات - بدلاً من تأمين الجدول أو الصف - طريقة سيئة للتعامل مع التزامن؛فهو يستبعد التزامن.

هناك العديد من البدائل المعقولة للاضطرار إلى تشفير قفل DMBS من نوع ما بنفسك.ضع في اعتبارك أن نوعًا ما من القفل يحدث دائمًا (الإجراءات الذرية، وما إلى ذلك) ولكن المفتاح هو أنك لا تريد الذهاب إلى هناك إذا لم تكن مضطرًا لذلك.لا ترغب في تناول العشاء مع الفلاسفة إذا لم تكن مضطرًا لذلك.تعد المعاملات إحدى الطرق للالتفاف على القفل، ولكن هذا في الغالب مخصص للالتزامات.يعد استخدام الحقل الذي يحدد/يشير إلى أن السجل متسخًا (نمط البت القذر) طريقة أخرى، فقط تأكد من أنك تفعل ذلك بطريقة الوصول الذري.غالبًا ما تحتوي اللغة على حل مناسب كما هو مشار إليه في المنشورات السابقة، إلا أن اللغة تدعم عادةً التطبيق وعملية المعالجة وتزامن المستوى وأحيانًا التزامن يجب أن يكون في قاعدة البيانات.لم أكن أريد أن أفترض أن لديك طبقة تطبيق غنية، ولكن إذا كان الأمر كذلك، فهناك العديد من طبقات التجريد التي تتعامل مع هذا الأمر نيابةً عنك.TopLink من Oracle مجاني وهو الأخ الأقوى لـ Hibernate وكلاهما يساعدك على إدارة تحديات التزامن في قاعدة البيانات الخاصة بك من خلال التجريد والبتات القذرة والتخزين المؤقت والقفل البطيء.أنت حقًا لا تريد تنفيذ هذه الأشياء بنفسك، إلا إذا كنت تقوم بالبرمجة لمشروع مدرسي أو شخصي.افهم المشكلة، ولكن قف على أكتاف العمالقة.

لا أعتقد ذلك، لأنه على طول الطريق "للأسفل" ويجعل تطبيقك أكثر تعقيدًا.تتمتع معظم اللغات بتقنيات ممتازة للتعامل مع التزامن، وحتى في هذه الحالة فإن أفضل طريقة هي كتابة تعليمات برمجية يمكنها التعامل مع التزامن "أصليًا".

لمزيد من المعلومات حول التزامن في Java:http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top