【问题标题】:Best way of using PreparedStatement executeBatch()使用 PreparedStatement executeBatch() 的最佳方式
【发布时间】:2013-06-20 07:11:51
【问题描述】:

我正在尝试找出使用 PreparedStatement executeBatch() 方法的最佳方式。

我尝试的一种方法是:

try{
    prepStmt1 = conn.prepareStatement("update table set done='yes' where phone=?");
    while (operatorsQuery.next() ) {
          logger.info("phone: "+ phone + ",  operator: " + operator);

          process(); //0.5-1 second long
          prepStmt1.setString(1, "0"+phone);
          prepStmt1.addBatch();
    }
prepStmt1.executeBatch();
}
catch{...}
finally{
    closeStatmentand(prepStmt1);
}

我在这段代码中遇到的问题是程序可以在中间退出,然后它可能无法到达 executeBatch() 方法。

我尝试的第二种方法:

try{
    prepStmt1 = conn.prepareStatement("update table set done='yes' where phone=?");
    while (operatorsQuery.next() ) {
          logger.info("phone: "+ phone + ",  operator: " + operator);

          process(); //0.5-1 second long
          prepStmt1.setString(1, "0"+phone);
          prepStmt1.addBatch();
          if ((j + 1) % 100 == 0) {
               prepStmt1.executeBatch();
          }
    }
prepStmt1.executeBatch();
}
catch{...}
finally{
    closeStatmentand(prepStmt1);
}

哪种方式最适合?

【问题讨论】:

  • 发布示例时确保它可以编译并运行
  • 您是在问是否应该将批次分解为已知大小(第二种情况下为 100?)
  • 在执行过程中可以关闭程序似乎很奇怪。如果程序结束是基于用户交互的,告诉用户他还没有完成并告知他后果。这样用户就可以决定是要丢失数据还是要等待。

标签: java sql prepared-statement


【解决方案1】:

通过使用批量更新,查询不会发送到数据库,除非有特定的调用 executeBatch(); 如果您担心用户可能会退出程序并且无法执行,为什么不执行更新一。并且连接默认设置为autoCommit(true);

如果应用程序已关闭,并且在调用 execute 的显式调用之前,查询尚未发送到数据库,则您无法调用提交。

执行增量批处理即可。

=======编辑=======

如果您的问题确实是性能问题,并且您遇到应用程序突然退出的问题,请尝试使用 Java 消息服务或 JMS。 JMS 使您能够异步发送消息,这意味着您的应用程序会将这些“数据”转发给 JMS,而不是等待响应,然后您将对 JMS 进行编程以将它们插入数据库。 JMS 也足够持久,当应用程序/服务器宕机时,发送的数据(也称为队列)在它恢复后仍然是活动的。

虽然 JMS 不适合初学者,而且很难从头开始实施。希望这可以帮助: http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html

【讨论】:

  • 我试过了,但它只需要很长时间,每 100 次迭代执行批处理似乎效率更高。
  • 我可以知道为什么应用程序会在进程中间退出吗?当应用程序意外退出时,您需要提交是不寻常的。
  • 是的,我知道它不寻常,正如您在代码中看到的那样,该应用程序产生了数千个 process()。每个过程应该只做一次!所以我保留数据库中已完成的每个进程的 id(在我的情况下为 phone_num)。
【解决方案2】:

https://examples.javacodegeeks.com/core-java/sql/jdbc-batch-update-example/

public void batchUpdateUsingStatement() throws SQLException {

// This is to hold the response of executeBatch()
int[] result = null;
try {
        Statement stmt = connection.createStatement();

        connection.setAutoCommit(false); // Setting auto-commit off
        String SQL = "update person set firstName='New First Name', lastName='New Last Name' where id=1";
        stmt.addBatch(SQL); // add statement to Batch
        SQL = "update person set firstName='First Name',lastName='Last Name' where id=2";
        stmt.addBatch(SQL); // add second statement to Batch
        result = stmt.executeBatch(); // execute the Batch
        connection.commit(); // commit
    } catch (SQLException e) {
        connection.rollback(); // rollBack in case of an exception
        e.printStackTrace();
    } finally {
        if (connection != null)
            connection.close(); // finally close the connection
    }
    System.out.println("Number of rows affected: " + result.length);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多