如何确保JDBC批处理插入以原子方式完成



我有以下(伪(代码,用于在SQL Server表中插入约5000行。我正在使用Hikari(下面的ds是我的HikariDataSource(。

try (Connection connection = ds.getConnection();
PreparedStatement statement = connection.prepareStatement(
"insert into Dog (name, age, breed) values (?, ?, ?)");) {


for (Dog d : dogs) {
statement.setString(1, d.getName());
statement.setInt(2, d.getAge());
statement.setString(3, d.getBreed());
statement.addBatch();
}

statement.executeBatch();
} 
// catch exceptions, etc. 

这很好(因为插入可以按预期工作(,但如果有人在批量插入过程中查询表(这需要几秒钟(,他们可能会得到一组不完整的行。我希望他们要么什么都不得到(假设表是空的(,要么我插入的每一行都不得到。

我认为我需要做一些特殊的事情来锁定表,或者以其他方式将所有插入作为单个事务执行(我认为这就是批量插入的原因,但我错了(。

我该怎么做?

默认情况下,连接处于自动提交模式。自动提交模式下批处理执行的事务行为取决于JDBC驱动程序的实现。如果您想确保它们是原子式完成的,则需要禁用自动提交模式,并在执行批处理后显式提交。

try (Connection connection = ds.getConnection();
PreparedStatement statement = connection.prepareStatement(
"insert into Dog (name, age, breed) values (?, ?, ?)");) {
connection.setAutoCommit(false);

for (Dog d : dogs) {
statement.setString(1, d.getName());
statement.setInt(2, d.getAge());
statement.setString(3, d.getBreed());
statement.addBatch();
}

statement.executeBatch();
connection.commit();
}

最新更新