【问题标题】:Bulk Update DB2 using Hibernate and Multi Threading使用 Hibernate 和多线程批量更新 DB2
【发布时间】:2019-02-05 15:40:41
【问题描述】:

我需要更新 DB2 数据库中超过 1000000 条记录。 我尝试将休眠与多线程应用程序一起使用来更新记录。但是,这样做我得到了 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|纯文本|加密文本

更新: 我尝试使用 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 条记录的代码:

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();

【问题讨论】:

  • 最好描述您使用的更新逻辑,并指定您是否能够在单个事务中执行此操作(您必须具有适当的事务日志大小)。
  • 另外,您应该描述操作要求。具体来说,批量更新运行时的并发要求。确保 Hibernate 生成的 UPDATE(或 MERGE)语句被索引,并且使用了合适的隔离级别。如果要更新的列被索引,或者是外键,或者有触发器,那么可能会应用不同的建议。 SO:您的问题太模糊,无法得到具体答案。
  • 运行此代码时,Hibernate 是否会先选择行,然后再更新它? (如果您还没有打开 SQL 日志记录。)您实际上并没有访问对象中的任何字段,因此无需读取它。一般来说,Hibernate 是一种糟糕的方式来进行这些更新;最好只使用 SQL。
  • 我也尝试了 JDBC 准备语句。但没有运气。更新了代码供参考。

标签: java hibernate exception db2


【解决方案1】:

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

您还应该确保有效地批量更新,而不是过于频繁地提交。

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

【讨论】:

    【解决方案2】:

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

    要捕获实际的 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 集是否存在某些条件?

    【讨论】:

    • 我们也可以在应用程序之外生成 ENCR_NUM 字段。我们需要为特定的 ID 更新这个值。问题是超过 1000000 需要在更短的时间内更新,这就是我想使用多线程的原因。
    • 那么,您为什么不想只使用像UPDATE INST1.ENCRYPT_REF SET ENCR_NUM=&lt;some_expression&gt; WHERE ID &lt;some_condition&gt; 这样的单个语句呢?使用这个会出现什么错误?
    • 我很乐意这样做。问题在于以最少的时间加载如此多的记录。如果我尝试多线程,它会导致锁定表。
    • 与这样的单个update 语句相比,即使多个同时连接执行单行更新,也很难相信您可以更快地完成此操作。唯一需要担心的是,这样一个update 可能会占用您系统的大量日志空间。
    • 您能否建议一种方法来在更短的时间内更新 DB2 中的这么多记录。
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 2017-10-06
    • 2013-07-11
    相关资源
    最近更新 更多