سؤال

هذا هو إصدار محدد من هذا السؤال.
أريد أن تحقق إذا أنا إدراج صف مكررة.يجب التحقق من ذلك برمجيا في طبقة التطبيقات:

if (exists(obj))
{
    throw new DuplicateObjectException();
}
HibernateSessionFactory.getSession().save(obj);

أو ينبغي أن قبض على استثناء القيت من قبل طبقة قاعدة البيانات و تشغيلها عندما تنتهك contraint?

try
{
    HibernateSessionFactory.getSession().save(obj);
}
catch(ConstraintViolationException e)
{
    throw new DuplicateObjectException();
}

تحرير: وبعبارة أخرى:على الرغم من القيد هو هناك أن تبقى (انها جيدة تصميم قاعدة البيانات على أي حال, أنا لا يمكن أن يكون متأكد من بلدي التطبيق سوف تكون واحدة فقط الوصول إلى الجدول) يجب الاعتماد على القيد والتعامل مع استثناء انتهاك رفع ، أو من الأفضل التحقق على أي حال ؟

EDIT2: بالطبع أنا لا تحقق+تدرج ضمن الصفقة ، تأمين الجدول للتأكد من أي عملية أخرى هي كتابة رقما قياسيا جديدا في هذه الأثناء

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

المحلول

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

بالنظر إلى أن القيد موجودا ، الطريقة التي يجب أن التعليمات البرمجية في التطبيق ؟ تفضيل بلدي سيكون محاولة إدراج وقبض على الاستثناءات.لأنه يفترض معظم إدراج سوف تنجح سوى عدد قليل سوف يفشل كما مكررة (هذا ما "استثناء" يعني!):فمن غير فعالة لإجراء موجود تحقق قبل كل إدراج قاعدة البيانات سوف يكون المنفذ الخاص القيد التحقق على أي حال.

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

نصائح أخرى

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

يجب القيام حفظ() وقبض على الاستثناء.وإلا لديك حالة سباق مع العملاء المتزامنة العمل على نفس قاعدة البيانات.

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

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

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

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

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

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

الاستثناءات التي القيت من قبل السبات (أو أي ORM مكون) تميل إلى أن يكون من الصعب تفسير.

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

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

السؤال هو "كيف مبهمة هو استثناء" ؟ بعض جدا مبهمة.آخرون بما فيه الكفاية التي يمكنك تحليل سلسلة رسالة ومعرفة ماذا أقول المستخدم.

مرة واحدة السبات يطرح استثناء من الدورة يجب التخلص من الدورة (انظر القسم 11.2.3).حتى, إذا كنت بحاجة إلى التحقق من dups و الاستمرار في استخدام نفس الدورة ثم لا يوجد لديك خيار سوى أن تحقق أولا في التطبيق.

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

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