使用休眠和多线程批量更新DB2

时间:2019-02-05 15:40:42

标签: java hibernate exception db2

我需要更新DB2数据库中的1000000条记录。 我尝试将休眠与多线程应用程序一起使用来更新记录。但是,这样做时我得到了lockacquisitionexception。我觉得这是因为我正在执行多个线程的大量提交。 有人可以推荐更好的解决方案或更好的方法吗? 如果需要上传正在使用的代码,请告诉我。 预先感谢。

1 - cdf()

表仅包含三列。 ID | PlainText | EncryptedText

更新: 我尝试使用JDBC准备的状态菜单进行批处理更新。但是,我仍然面临以下异常:

  

com.ibm.db2.jcc.am.BatchUpdateException:   [jcc] [t4] [102] [10040] [3.63.75]批处理失败。该批次是   提交,但单个成员至少发生一个例外   的批次。使用getNextException()检索以下异常   特定的批处理元素。 ERRORCODE = -4229,SQLSTATE = null,位于   com.ibm.db2.jcc.am.fd.a(fd.java:407)在   com.ibm.db2.jcc.am.n.a(n.java:386)在   com.ibm.db2.jcc.am.zn.a(zn.java:4897)在   com.ibm.db2.jcc.am.zn.c(zn.java:4528)在   com.ibm.db2.jcc.am.zn.executeBatch(zn.java:2837)在   org.npci.ThreadClass.run(ThreadClass.java:63)在   java.lang.Thread.run(Thread.java:748)

下面是执行的批量大小为50-100条记录的代码:

//Code running multiple times with threads 
Transaction tx = null; 
tx = session.beginTransaction(); 
for(EncryptRef abc : arList) { 
String encrypted = keyUtils.encrypt(abc.getNumber()); //to encrypt some data
Object o = session.load(EncryptRef.class,new Long(abc.getId())); //primary key EncryptRef object = (EncryptRef)o; 
object.setEncryptedNumber(encrypted); //updating the row 
} 
tx.commit(); //bulk commiting the updates

2 个答案:

答案 0 :(得分:0)

在不了解数据库结构的情况下,很难推荐特定的解决方案。如果可以更改数据库,一个好的策略是对表进行分区,然后安排每个线程更新一个单独的分区。不必让多个线程来更新一个大型数据库并彼此冲突,而是可以有效地使每个线程都更新自己的较小数据库。

您还应该确保有效地批处理更新并且不要过于频繁地提交。

如果您的表具有大量索引,那么在更新后删除部分/全部并进行重建可能比持续进行更新更为有效。同样,您可以考虑删除触发器,参照完整性约束等,然后稍后进行修补。

答案 1 :(得分:0)

不是问题的答案。用于更好的格式。

要捕获实际的db2 SQLCODE,请使用以下技术。否则,不可能理解问题的根本原因。

try {
  ...
} catch (SQLException ex) {
    while (ex != null) {
        if (ex instanceof com.ibm.db2.jcc.DB2Diagnosable) {
            com.ibm.db2.jcc.DB2Diagnosable db2ex = 
        (com.ibm.db2.jcc.DB2Diagnosable) ex;
            com.ibm.db2.jcc.DB2Sqlca sqlca = db2ex.getSqlca();
            if (sqlca != null) {
              System.out.println("SQLCODE: " + sqlca.getSqlCode());
              System.out.println("MESSAGE: " + sqlca.getMessage());
            } else {
            System.out.println("Error code: " + ex.getErrorCode());
            System.out.println("Error msg : " + ex.getMessage());
            }
        } else {
        System.out.println("Error code (no db2): " + ex.getErrorCode());
        System.out.println("Error msg  (no db2): " + ex.getMessage());
      }
        ex = ex.getNextException();
    }
    ...
}

关于ENCR_NUM字段。 在您的应用程序之外是否可以具有此列的实际值? 还是这些值只能由您的应用程序生成?

您是否必须更新所有表行,或者ID集合上是否有需要更新的条件?