澄清Java / SQLite批处理和自动提交

时间:2012-03-18 00:11:39

标签: java sql sqlite

我从SQLite Java库网站复制了以下示例:

PreparedStatement prep =
         conn.prepareStatement("insert into people values (?, ?);");
prep.setString(1, "Gandhi");
prep.setString(2, "politics");
prep.addBatch();
prep.setString(1, "Turing");
prep.setString(2, "computers");
prep.addBatch();
conn.setAutoCommit(false);
prep.executeBatch();
conn.setAutoCommit(true);

我正在努力理解切换autoCommit() executeBatch()任何一方的重要性。它是否仅仅阻止了对每个批处理操作的提交?因此,setAutoCommit(true)将进行单个“批量”提交。

3 个答案:

答案 0 :(得分:10)

自动提交在批处理前被禁用,因为启用自动提交将提交(即等待同步发生,这意味着它将在插入的每一行之后等待数据实际写入持久存储,如硬盘)。

如果auto commit为false,则不会等待同步。

等待同步而不是等待的区别在于保证数据是实际上是硬盘还是缓冲区(可以是缓冲IO或硬盘缓冲区)。

简而言之,禁用自动提交可以提升性能。我认为默认情况下会启用自动提交。

另一种优化方式

如果您希望自动提交并仍需要性能提升,请尝试在批处理操作之前启动事务并在之后提交事务。这样sqlite在每次插入后都不会自动提交,会提高性能。

编辑:

启动事务时,您只能禁用自动提交 对于该交易,一旦交易结束,它将再次“开启”。什么自动提交有帮助 当你单独插入/更新行(而不是批处理)时,你不必开始一个 每个插入/更新显式事务。关于将自动提交设置为true,之后 事实上,不要求提交。如果您进行自动提交 是的,无论你已经插入/更新了什么都没有任何效果,也不会有相同的效果 在进行插入/更新之前,保证为自动提交。

Here's some information about speeding up Sqlite INSERTs.

答案 1 :(得分:4)

这里的答案和评论中分享了一些错误的信息,所以我想我会添加一个答案。

  1. 仅供参考,SQLite不支持直接自动提交。在SQLite JDBC连接上调用setAutoCommit(false)实际上会启动与Xerial和Zentus驱动程序的事务。请参阅此问题:How to disable autocommit in sqlite4java?

  2. 我几乎肯定将自动提交设置为true将对数据库连接进行提交。完成的下一个语句将保留所有未完成的更改,但您必须执行conn.commit();才能实际提交批处理操作。

  3. 启动事务基本上与关闭自动提交相同,因此暗示您可以在事务内部启用自动提交是不恰当的。

答案 2 :(得分:0)

对我有用的是设置以下内容:

        con.setAutoCommit(false);
        con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        ps1.executeUpdate();
        ps2.executeUpdate();
        con.commit();
        con.setAutoCommit(true);