java中jdbc实现“每五千条数据刷盘一次”的批量提交,需关闭自动提交、分批addbatch并executebatch+commit,配合rewritebatchedstatements=true参数提升mysql性能,同时注意clearbatch、异常回滚与内存控制。

Java 中 JDBC 实现“每五千条数据刷盘一次”的批量提交,核心在于两层控制:一是用 addBatch() 积累语句,二是用 executeBatch() + commit() 分段执行与持久化。这里的“刷盘”实际指事务提交(commit()),它会触发数据库将日志写入磁盘(如 MySQL 的 redo log fsync),确保数据持久化。
设置手动事务并分批提交
默认情况下 JDBC 是自动提交模式,每条 SQL 执行完立刻落盘。要实现精细控制,必须关闭自动提交,并在每满 5000 条时显式提交:
- 调用
conn.setAutoCommit(false)禁用自动提交 - 循环中逐条设置参数、调用
ps.addBatch() - 每累计到 5000 条(即
i % 5000 == 0),执行ps.executeBatch()和conn.commit() - 每次执行后调用
ps.clearBatch()清空缓存,避免重复执行 - 循环结束后,检查是否还有剩余未提交的语句(如总数不是 5000 的整数倍),再执行一次
executeBatch()+commit()
注意 MySQL 驱动的 rewriteBatchedStatements 参数
仅靠 JDBC 的 addBatch 默认不会真正合并为一条 SQL 发送给 MySQL;它只是客户端批量发送多条独立语句。若想让 MySQL 服务端真正以 INSERT ... VALUES (...), (...), (...) 形式高效执行,需在 JDBC URL 中启用优化:
务必添加参数:?rewriteBatchedStatements=true
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
例如:jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true&useSSL=false
否则即使你调用了 executeBatch(),抓包可见仍是 5000 条独立 INSERT,性能提升有限。
防内存溢出与异常回滚
处理大批量数据时,不能把全部 100 万条都攒在内存里再提交——容易 OOM。按 5000 条分段既是刷盘节奏,也是内存安全策略:
- 每批执行后立即
clearBatch(),释放 PreparedStatement 内部缓冲 - 外层 try-catch 包裹整个流程,捕获
BatchUpdateException或SQLException - 发生异常时,调用
conn.rollback()回退当前批次(注意:只回退尚未 commit 的那部分) - 建议配合连接池使用,并确保连接未被超时中断
完整关键代码片段
(省略资源关闭等样板,聚焦逻辑)
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement("INSERT INTO t_user(name, age) VALUES (?, ?)");
for (int i = 0; i
ps.setString(1, "user" + i);
ps.setInt(2, i % 100);
ps.addBatch();
if ((i + 1) % 5000 == 0) {
ps.executeBatch();
conn.commit();
ps.clearBatch();
}
}
// 提交剩余不足 5000 条的部分
if (totalRecords % 5000 != 0) {
ps.executeBatch();
conn.commit();
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










