如何确保以原子方式完成 JDBC 批量插入?

     2023-02-15     109

关键词:

【中文标题】如何确保以原子方式完成 JDBC 批量插入?【英文标题】:How can I ensure that a JDBC batch insert is done atomically? 【发布时间】:2022-01-19 20:18:21 【问题描述】:

我有以下(伪)代码将约 5000 行插入到 SQL Server 表中。我正在使用 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. 

这工作正常(插入按预期工作),但如果有人在批量插入中间查询表(这需要几秒钟),他们可能会得到一组不完整的行。我希望他们要么一无所获(假设表一开始是空的),要么我插入的每一行。

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

我该怎么做?

【问题讨论】:

SQL Server 可以轻松地一次性快速插入 1,000 行(甚至数百万行)。事实上,5,000 个单独的 INSERT 语句将比 5,000 行的单个语句慢得多。如果您可以传递表格类型参数/变量,那么您可以一次性INSERT 这么多,不会让人得到公正的结果,而且会更快。 @Larnu Hmmm - 1)“传递表类型参数/变量”是什么意思?和 2)我正在做一个批量插入,我“一次”插入所有东西(或者我想) - 我不是通过批量插入“一次性插入全部”吗? 基本上听起来像什么。它是一个表类型的参数。不,包含 5,000 个 INSERT 语句的批处理不会同时插入所有这些行; SQL一个接一个地运行批处理中的每个语句,因此批处理中的每个语句将按顺序运行。 @DanGuzman 这是否就像在迭代 Dogs 之前添加 connection.setAutoCommit(false); 并在 statement.executeBatch() 之后添加 connection.commit() 一样简单? 见Using table-valued parameters。这个example 似乎很相关。 【参考方案1】:

默认情况下,连接处于自动提交模式。自动提交模式下批处理执行的事务行为取决于 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();

【讨论】:

如何优化 Oracle 11g 和 Hibernate 的批量插入?

】如何优化Oracle11g和Hibernate的批量插入?【英文标题】:HowdoIoptimizebatchINSERTsforOracle11gandHibernate?【发布时间】:2016-03-2802:26:08【问题描述】:我有一个执行相当多的批量插入的应用程序。我想优化应用程序以尽可能快地完成这些... 查看详情

jdbc连hive怎么批量插入

参考技术A2、JDBC连接的方式,当然还有其他的连接方式,比如ODBC等,这种方式很常用,可以在网上随便找到,就不再累赘了。不稳定,经常会被大数据量冲挂,不建议使用。3、这种方式是直接利用Hive的Driverclass来直接连接,感... 查看详情

如何从 Oracle 中的 JDBC 批量插入中获取生成的密钥?

】如何从Oracle中的JDBC批量插入中获取生成的密钥?【英文标题】:HowtogetgeneratedkeysfromJDBCbatchinsertinOracle?【发布时间】:2013-03-1900:52:03【问题描述】:我正在使用JDBC批量插入插入许多记录。有什么方法可以获取每条记录的生成密... 查看详情

以原子方式比较-交换 Django 中的模型字段

...elFieldinDjango【发布时间】:2016-10-3117:03:16【问题描述】:如何以原子方式比较-交换-保存DjangoModel实例Field的值?(使用PostgreSQL作为数据库后端)。一个示例用例是确保具有相似内容的多个帖子(例如,提交相同表单)仅生效一... 查看详情

hibernate的批量插入(&&jdbc)

一、批量插入(两种方式)1,通过hibernate缓存如果这样写代码进行批量插入(初始设想):packagecom.anlw.util;importorg.hibernate.Session;importorg.hibernate.SessionFactory;importorg.hibernate.Transaction;importorg.hibernate.boot.registry.Sta 查看详情

使用jdbc一次插入多条记录(以mysql为例)

...实对于需要INSERT或者UPDATE多条记录的情况,JDBC也提供了批量更新的机制。1.事务批量更新基于事务处理,JDBC提供了两个方法voidcommit()和void 查看详情

jdbc解析excel文件,批量插入数据至库中

...了个这样的需求,解析excel表中的数据,以JDBC的方式,将数据批量更新至不同的数据表中。注意,更新指的是:如果数据表中有该条记录,则更新操作&#x 查看详情

对 JDBC 批量更新的所有行进行原子锁定

】对JDBC批量更新的所有行进行原子锁定【英文标题】:AtomiclockingofallrowsofaJDBCbatchupdate【发布时间】:2019-04-1112:57:08【问题描述】:我有两个线程在一个表上运行并发更新,类似于:CREATETABLET(SEQNUMBER(10)PRIMARYKEY,VAL1VARCHAR2(10),VAL2VAR... 查看详情

百万级别数据批量插入mysql,哪种方式最快?

3种策略源码地址Mybatis轻量级框架插入-数据量500WJDBC直接处理-数据量10WJDBC开启自动提交JDBC关闭自动提交采用JDBC批处理-数据量100W自动提交关闭自动提交JDBC批处理-数据量100W自动提交关闭自动提交总结:源码地址源码Mybatis轻... 查看详情

jdbc中的批量插入和乱码解决

...们可以在DB_URL字符串后加上”?characterEncoding=XXX”的方式指定JDBC使用的字符集。 同时,我们需要知道MySql中使用的字符集,可以通过以下两个 查看详情

以原子方式写入文件与不写入文件之间的区别

】以原子方式写入文件与不写入文件之间的区别【英文标题】:Differencebetweenwritingtofileatomicallyandnot【发布时间】:2010-04-2415:48:02【问题描述】:objective-c在iPhone上以原子方式写入文件有什么区别,两者之间有什么性能差异吗?【... 查看详情

批量插入是原子的吗?

】批量插入是原子的吗?【英文标题】:Isbulkinsertatomic?【发布时间】:2010-09-0914:32:17【问题描述】:我有带有自动递增主键的表。我想在其中插入一堆数据并获取每个数据的键,而无需额外查询。STARTTRANSACTION;INSERTINTOtable(value)VA... 查看详情

NEST 批量插入后等待服务器完成索引

...dexManyAsync(docs,myAlias,cancellationToken);对于我的测试,我需要确保可以100%保证查询索引文档,因为在 查看详情

如何以原子方式使用两个 NotifyDataSetChanged()

】如何以原子方式使用两个NotifyDataSetChanged()【英文标题】:HowtouseTwoNotifyDataSetChanged()Atomically【发布时间】:2021-01-3105:38:48【问题描述】:总结一下我的问题:我有一个项目列表和一个按钮,我可以单击它来查询API当我单击按钮... 查看详情

如何以原子方式更新最大值?

】如何以原子方式更新最大值?【英文标题】:Howtoatomicallyupdateamaximumvalue?【发布时间】:2013-04-1721:23:26【问题描述】:在串行代码中,更新最大值可以简单地通过template<typenameT>voidupdate_maximum(T&maximum_value,Tconst&value)noex... 查看详情

Java:如何使用用于 Sql Server 的 java jdbc 执行带有标识列的批量插入

】Java:如何使用用于SqlServer的javajdbc执行带有标识列的批量插入【英文标题】:Java:howtoperformbatchinsertwithidentitycolumnusingjavajdbcforSqlServer【发布时间】:2019-03-1815:06:34【问题描述】:我有一个csv文件,我需要使用SQLServerBulkCopy将其... 查看详情

如何以原子方式删除和获取行数据? [关闭]

】如何以原子方式删除和获取行数据?[关闭]【英文标题】:HowcanIdeleteandgettherowdatainanatomicway?[closed]【发布时间】:2019-08-0715:59:06【问题描述】:我在表列中存储了一次性密钥。我有一个表,它只包含唯一键,一旦读取和发送,... 查看详情

如何提高批量插入效率?

1、将连接参数rewriteBatchedStatements设为trueConnectionc=DriverManager.getConnection("jdbc:mysql://host:3306/db?useServerPrepStmts=false&rewriteBatchedStatements=true","username","password");2、原生SQL批量插入ST 查看详情