澄清Java / 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); 

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

谢谢。

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

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

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

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

另一种优化方式

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

编辑:

当您启动事务时,您只会禁用该事务的自动提交,并且一旦事务结束,它将再次“打开”。 什么自动提交有助于单独插入/更新行(而不是批处理),然后您不必为每个插入/更新显式启动事务。 关于将auto-commit设置为true,事实上,不会调用commit。 如果你使自动提交成为真,那​​么你已插入/更新的任何内容都不会产生任何影响,并且在进行那些插入/更新之前不会像自动提交那样保持相同的保证。

这里有一些关于加速Sqlite INSERT的信息。

@havexz回答给出了一些错误的信息,所以我想我会为后代添加一个答案。

  1. 仅供参考,SQLite不支持直接自动提交。 在SQLite JDBC连接上调用setAutoCommit(false)实际上会启动与Xerial和Zentus驱动程序的事务。 看到这个问题: 如何在sqlite4java中禁用自动提交?

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

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