ExecuteBatch不会执行一次,而是在每条记录之后执行。为什么?

时间:2014-07-22 09:47:16

标签: java sql sqlite

这是我的代码:

    prodsQuery = dbc
                .connect()
                .prepareStatement(
                        "INSERT INTO 'duplicates' (C_ContactID, C_EmailAddress, 
C_DataSourceID, C_DateCreated)"
                                + "VALUES (?,?,?,?);");
        // for (Record x : records) {

        for (int i = startAtRecord; i <= records.size(); i++) {
            prodsQuery.setInt(1, records.get(i).getContactID());
            prodsQuery.setString(2, records.get(i).getEmail());
            prodsQuery.setString(3, records.get(i).getDataSourceID());
            prodsQuery.setString(4, records.get(i).getDateCreated());

            // addBatch is better than executeUpdate or executeQuery in this
            // case
            prodsQuery.addBatch();
            // save number of record in case of failure
            BufferedWriter out = new BufferedWriter(new FileWriter(
                    "data\\resumerecord.txt"));
            out.write(i + "\n");
            out.close();
            // execute batch every some records, in case of failure to start
            // at some point
            if (i % 5000 == 0) {
                prodsQuery.executeBatch();
                System.out.println("Batch was executed.");

            }

        }
        prodsQuery.executeBatch();
        prodsQuery.close();

我想要有效,这就是为什么我要每5000条记录执行一次批处理。但是当我进行测试时,我意外地关闭了程序,然后查看了DB并发现它在记录7589处停止。这意味着它正在逐个添加记录。

为什么呢?

不应该将整个块插入其中吗?

我认为这就是为什么批次更有效的原因。

还有没有其他方法可以存储完成插入的记录的ID?也许在程序启动时从db读取它。

2 个答案:

答案 0 :(得分:1)

只要您处于自动提交模式,每个INSERT语句都将拥有自己的自动事务。 这也适用于executeBatch执行的语句;该功能将为您创建单个交易。

提交交易是该计划中最耗时的部分,因此中止程序的可能性会发生在executeBatch循环中间的某个地方。

要减少交易开销,请禁用自动提交模式,然后在连接上手动呼叫commit

答案 1 :(得分:1)

您应该在batch insert内执行transaction。在事务内执行时,您可以确保执行所有更新,或者不更新任何更新。

您应该始终使用自动提交模式运行SQL查询,即使使用JDBC Batch insert and update也会自动执行commit()

类似这样的事情

try{
    connection.setAutoCommit(false);
    // add to batch and execute batch
    connection.commit();
    } catch (SQLException e) {
      e.printStackTrace();
    }
finally{
//closing statements
   }