أفضل طريقة لإدارة اتصال قاعدة البيانات لـ Java servlet

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

سؤال

ما هي أفضل طريقة لإدارة اتصال قاعدة البيانات في Java servlet؟

حاليًا، أقوم ببساطة بفتح اتصال في init() الوظيفة، ثم أغلقها destroy().

ومع ذلك، أشعر بالقلق من أن الاحتفاظ "بشكل دائم" باتصال قاعدة البيانات قد يكون أمرًا سيئًا.

هل هذه هي الطريقة الصحيحة للتعامل مع هذا؟إذا لم يكن الأمر كذلك، ما هي بعض الخيارات الأفضل؟

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

هل هناك أي قيمة في مشاركة اتصال عبر طلبات متعددة؟طلبات هذا التطبيق كلها تقريبًا "للقراءة فقط" وتأتي بسرعة إلى حد ما (على الرغم من أن البيانات المطلوبة صغيرة إلى حد ما).

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

المحلول

وأنا في الواقع لا يوافقون على استخدام العموم DBCP. يجب أن تؤجل حقا إلى الحاوية لإدارة تجمع الاتصال لك.

ومنذ كنت تستخدم جافا سيرفلتس، فإن هذا يعني تشغيل في حاوية بريمج، وجميع الحاويات بريمج الرئيسية التي أنا على دراية توفير إدارة تجمع الاتصال (حتى المواصفات جافا EE قد تتطلب ذلك). إذا يحدث حاوية لاستخدام DBCP (كما يفعل القط)، وكبيرة، وإلا، ومجرد استخدام كل ما توفر الحاويات الخاصة بك.

نصائح أخرى

كما يقول الجميع، تحتاج إلى استخدام تجمع اتصال.لماذا؟ما يصل؟إلخ.

ما هو الخطأ في الحل الخاص بك

أعرف هذا لأنني اعتقدت أيضًا أنها كانت فكرة جيدة ذات مرة.المشكلة ذات شقين:

  1. ستشارك جميع سلاسل الرسائل (يتم تقديم طلبات servlet بموضوع واحد لكل منها) في نفس الاتصال.وبالتالي ستتم معالجة الطلبات واحدًا تلو الآخر.وهذا بطيء جدًا، حتى لو كنت تجلس في متصفح واحد وتتكئ على المفتاح F5.جربها:تبدو هذه الأشياء عالية المستوى ومجردة، لكنها تجريبية وقابلة للاختبار.
  2. إذا انقطع الاتصال لأي سبب من الأسباب، فلن يتم استدعاء أسلوب init مرة أخرى (لأنه لن يتم إخراج servlet من الخدمة).لا تحاول التعامل مع هذه المشكلة عن طريق محاولة الالتقاط في doGet أو doPost، لأنك حينها ستكون في الجحيم (نوعًا ما تكتب خادم تطبيق دون أن يُطلب منك ذلك).
  3. على عكس ما قد يعتقده المرء، لن تواجه مشاكل في المعاملات، حيث أن بداية المعاملة ترتبط بسلسلة المحادثات وليس الاتصال فقط.قد أكون مخطئًا، ولكن نظرًا لأن هذا حل سيئ على أي حال، فلا تقلق.

لماذا تجمع الاتصال

تمنحك تجمعات الاتصال مجموعة كاملة من المزايا، ولكن الأهم من ذلك كله أنها تحل مشاكل

  1. إن إجراء اتصال حقيقي بقاعدة البيانات أمر مكلف.يحتوي تجمع الاتصال دائمًا على عدد قليل من الاتصالات الإضافية ويمنحك واحدة منها.
  2. إذا فشلت الاتصالات، يعرف تجمع الاتصالات كيفية فتح تجمع جديد
  3. مهم جدا:كل موضوع يحصل على اتصال خاص به.هذا يعني أنه يتم التعامل مع الترابط حيث ينبغي أن يكون:على مستوى قاعدة البيانات.تتميز قواعد البيانات بالكفاءة الفائقة ويمكنها التعامل مع الطلبات المتزامنة بسهولة.
  4. أشياء أخرى (مثل الموقع المركزي لسلاسل توصيل JDBC، وما إلى ذلك)، ولكن هناك ملايين المقالات والكتب وما إلى ذلك.على هذا

متى تحصل على اتصال

في مكان ما في مكدس الاستدعاءات الذي بدأه مندوب الخدمة الخاص بك (doPost، doGet، doDisco، أيًا كان) يجب أن تحصل على اتصال ثم يجب عليك القيام بالشيء الصحيح وإعادته في كتلة نهائية.يجب أن أذكر أن المهندس المعماري الرئيسي لـ C# قال ذات مرة أنه يجب عليك استخدامه finally كتل 100x أكثر من catch كتل.أصدق الكلمات لم تقال قط..

أي تجمع اتصال

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

تقترح بعض التعليقات على الإجابات أعلاه استخدام واجهة برمجة تطبيقات تجمع اتصالات معينة بدلاً من ذلك.يجب أن تكون حربك محمولة و "مجرد نشر". أعتقد أن هذا خطأ في الأساس.إذا كنت تستخدم مجمع الاتصال الذي توفره الحاوية الخاصة بك، فسيكون تطبيقك قابلاً للنشر على الحاويات التي تمتد على أجهزة متعددة وكل تلك الأشياء الرائعة التي توفرها مواصفات Java EE.نعم، يجب كتابة واصفات النشر الخاصة بالحاوية، ولكن هذه هي طريقة EE، يا مون.

يذكر أحد المعلقين أن بعض مجموعات الاتصال المتوفرة بالحاويات لا تعمل مع برامج تشغيل JDBC (ذكر/ذكرت Websphere).يبدو هذا بعيد المنال وسخيفًا تمامًا، لذا فمن المحتمل أن يكون صحيحًا.عندما تحدث أشياء كهذه، قم بإلقاء كل ما "من المفترض أن تفعله" في سلة المهملات وافعل كل ما بوسعك.هذا ما نتقاضاه أحيانًا :)

وكنت تستخدم العموم DBCP . انها مشروع أباتشي التي تدير تجمع الاتصال لك.

وأنت تريد فقط الحصول على اتصال بك في doGet أو doPost تشغيل الاستعلام الخاص بك ثم أغلق الاتصال في منع أخيرا. (con.close () فقط يعود إلى تجمع، لا في الواقع إغلاقه).

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

هل تجميع الاتصالات الخاصة بك؟ إذا لم يكن كذلك، ربما يجب عليك للحد من النفقات العامة لفتح وإغلاق الاتصالات.

وبمجرد أن الخروج من الطريق، وتبقي فقط الاتصال مفتوحة لفترة طويلة كما انها الحاجة، كما اقترح جون.

وأفضل وسيلة، وأنا أبحث حاليا عن طريق Google للورقة مرجعية أفضل، هو استخدام حمامات.

في التهيئة، يمكنك إنشاء تجمع يحتوي على عدد X من كائنات الاتصال SQL إلى قاعدة البيانات الخاصة بك. تخزين هذه الكائنات في بعض النوع من قائمة، مثل ArrayList. كل من هذه الكائنات لديها منطقية الخاصة ل 'isLeased، طويل عن الوقت الذي كان الأخير المستخدمة واتصال. كلما كنت في حاجة الى الاتصال، طلب واحد من التجمع. سوف تجمع إما تعطيك أول اتصال متوفرة، والتحقق على المتغير isLeased، أو أنه سيتم إنشاء واحدة جديدة وإضافته إلى حوض السباحة. تأكد من تعيين الطابع الزمني. بمجرد الانتهاء من ذلك مع اتصال، والعودة ببساطة إلى المجمع، الذي سيحدد isLeased إلى false.

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

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

ويجب أن تعقد فقط اتصال قاعدة بيانات مفتوحة لطالما كنت في حاجة إليها، والتي تعتمد على ما تفعلونه هو على الارجح في نطاق الأساليب doGet/doPost الخاص بك.

وبركة ذلك.

وبالإضافة إلى ذلك، إذا كنت تفعل JDBC الخام، هل يمكن أن ننظر إلى شيء يساعدك على إدارة اتصال، PreparedStatement، وما إلى ذلك إلا إذا كان لديك ضيق جدا متطلبات "lightweightness"، وذلك باستخدام الدعم JDBC الربيع، على سبيل المثال، يتم الانتقال إلى تبسيط التعليمات البرمجية لlot- بالجملة وأنت لا يضطر إلى استخدام أي جزء آخر من الربيع.

وانظر بعض الأمثلة هنا:

http://static.springframework.org/spring /docs/2.5.x/reference/jdbc.html

وتجمع اتصال يرتبط مع مصدر البيانات ينبغي أن تفعل خدعة. يمكنك الحصول على عقد من الاتصال من مصدر البيانات في طريقة طلب بريمج (doget / dopost، الخ).

وDBCP، c3p0 والعديد من برك اتصال أخرى يمكن أن تفعل ما كنت تبحث عنه. بينما كنت تجميع الاتصالات، قد ترغب في تجميع البيانات وPreparedStatements. أيضا، إذا كنت بيئة الثقيلة READ كما أشرت، قد ترغب في تخزين بعض النتائج باستخدام شيء من هذا القبيل ehcache.

وBR،
~ A

وعادة ما سوف تجد أن فتح اتصالات لكل طلب هو أسهل لإدارة. وهذا يعني في doPost () أو doGet () طريقة بريمج الخاص بك.

وفتحه في الحرف الأول () يجعل من متاحة لجميع الطلبات وما يحدث عندما يكون لديك الطلبات المتزامنة؟

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