使用Hibernate和多线程批量更新DB2

问题描述 投票:0回答:2

我有一个要求,更新超过100万条记录在DB2数据库中。我尝试使用Hibernate的多线程应用程序更新的记录。然而,这样做我得到lockacquisitionexception。我觉得这是因为批量提交我与多线程一起做的。有人可以推荐一个更好的解决方案或更好的方式来做到这一点。请让我知道,如果我需要上传我使用的代码。提前致谢。

//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

表只包含三列。 ID |纯文本| EncryptedText

更新:使用JDBC我想批量更新准备statemenets。不过,我仍然面临以下异常:

com.ibm.db2.jcc.am.BatchUpdateException:[JCC] [T4] [102] [10040] [3.63.75]批次故障。将该批次提交,但出现了一批个人会员至少一个例外。使用的getNextException()检索特定元素成批例外。 ERRORCODE = -4229,SQLSTATE =空处com.ibm.db2.jcc.am.na(n.java:386)com.ibm.db2.jcc.am.fd.a(fd.java:407)在玉米.ibm.db2.jcc.am.zn.a(zn.java:4897)处com.ibm.db2.jcc.am com.ibm.db2.jcc.am.zn.c(zn.java:4528) .zn.executeBatch(zn.java:2837)在org.npci.ThreadClass.run(ThreadClass.java:63)在java.lang.Thread.run(Thread.java:748)

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

String queryToUpdate = "UPDATE INST1.ENCRYPT_REF SET ENCR_NUM=? WHERE ID=?";
            PreparedStatement pstmtForUpdate = conn.prepareStatement(queryToUpdate);
            for (Map.Entry<Long,String> entry : encryptMap.entrySet()) {
                pstmtForUpdate.setString(1, entry.getValue());
                pstmtForUpdate.setLong(2, entry.getKey());
                pstmtForUpdate.addBatch();
            }
            pstmtForUpdate.executeBatch();
            conn.close();
java hibernate exception db2
2个回答
0
投票

不知道你的数据库结构的任何很难提出具体的解决方案。如果你能更改数据库,一个好的策略是你的分区表,然后安排每个线程更新一个单独的分区。相反,具有多线程更新一个庞大的数据库,并互相冲突的,你将有效地让每个线程的每个更新自己的数据库较小。

你也应该确保你有效配料的更新和未提交过于频繁。

如果你的表有吨指标,它可能是更有效的减少一些/所有和你更新后重建,而不是再更新持续进行。类似的,你可以考虑删除触发器,参照完整性约束等,然后再修补。


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的一些情况?

© www.soinside.com 2019 - 2024. All rights reserved.