سؤال

أحتاج إلى تنفيذ تحديد ثم تحديث بعض الصفوف في ملف ResultSet بطريقة ذرية.

يبدو الكود الذي أستخدمه (مبسطًا):

stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery("SELECT ...");

while (rs.next()) {
    if (conditions_to_update) {
        rs.updateString(...);
        rs.updateRow();
    }
}
  • هل يمكنني ضمان أن التحديثات سيتم تنفيذها تلقائيًا؟إذا لم يكن الأمر كذلك، فكيف يمكنني التأكد من ذلك؟
  • ماذا يحدث إذا أدت أي عملية أخرى إلى تغيير صف قاعدة البيانات الذي تقوم بالتحديث من خلاله updateRow() ؟هل هناك أي طريقة لقفل الصفوف في ملف ResultSet ?
هل كانت مفيدة؟

المحلول

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

كما ذكر ياسيفك، يجب أن تنظر في استخدام المعاملات للتأكد من الطبيعة الذرية لتحديثاتك - من الأمثلة ذات المستوى المنخفض جدًا القيام بشيء على غرار:

...
con.setAutoCommit(false);
try {
  while (rs.next()) {
    if (conditions_to_update) {
      rs.updateString(...);
      rs.updateRow();
    }
  }
  con.setAutoCommit(true);
} catch (Exception ex) {
  //log the exception and rollback
  con.rollback();
} finally {
  con.close();
}

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

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

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

يتمثل الأسلوب الأكثر تعقيدًا في التأكد من تنفيذ طرق إجراء هذه التحديثات بطريقة آمنة لمؤشر الترابط.إلى تلك النهاية:

  • كافة التحديثات لهذا الجدول تمر عبر فئة واحدة
  • تطبق هذه الفئة نمطًا مفردًا، أو تعرض طرق التحديث كطرق ثابتة
  • تستخدم طرق التحديث متزامن الكلمة الأساسية لمنع ظروف السباق

نصائح أخرى

استخدام المعاملات.

ماذا يحدث إذا أدت أي عملية أخرى إلى تغيير صف قاعدة البيانات الذي تقوم بتحديثه عبر updateRow() ؟هل هناك أي طريقة لقفل الصفوف في ResultSet؟

في Oracle، يمكنك وضع علامة على صفوف معينة للتحديث عن طريق إصدار SQL التالي.

select cola, colB from tabA for update;

المعاملة/السلسلة/التطبيق التالي الذي يحاول تحديث هذا الصف سيحصل على استثناء.انظر هذا لمزيد من التفاصيل-- http://asktom.Oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4530093713805

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