java preparedstatement 执行批量数据容灾的核心做法是结合事务管理与异常回滚机制,确保在批量插入或更新过程中,一旦某条数据出错,整个批次要么全部成功,要么全部撤销,从而避免产生脏数据。具体实现时,需关闭自动提交(auto-commit),通过 addbatch() 收集 sql 参数,并在 executebatch() 捕获异常后调用 rollback() 恢复数据库状态。

如何配置连接以支持事务控制
要实现容灾,第一步是获取 JDBC 连接并禁用自动提交模式。默认情况下,JDBC 连接处于自动提交状态,每条语句执行后立即持久化,这会导致部分成功、部分失败的数据残留。通过调用 connection.setAutoCommit(false),可以将多条操作纳入同一个事务中,直到显式调用 commit() 才生效。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class BatchTransactionDemo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// 1. 关闭自动提交
conn.setAutoCommit(false);
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 模拟批量数据
String[][] data = {{"Alice", "alice@example.com"}, {"Bob", "bob@example.com"}};
for (String[] row : data) {
pstmt.setString(1, row[0]);
pstmt.setString(2, row[1]);
pstmt.addBatch();
}
// 2. 执行批量
int[] results = pstmt.executeBatch();
// 3. 提交事务
conn.commit();
System.out.println("Batch executed successfully. Results: " + java.util.Arrays.toString(results));
} catch (Exception e) {
// 4. 发生异常时回滚
conn.rollback();
System.err.println("Error occurred, transaction rolled back.");
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
上述代码展示了完整的流程:先设置 setAutoCommit(false),然后循环调用 addBatch() 添加参数,最后调用 executeBatch()。如果中间任何一步抛出异常,程序进入 catch 块并执行 conn.rollback(),保证数据库状态不变。预期输出为控制台打印成功信息,若数据中存在非法值导致 SQL 错误,则打印错误信息且数据库中无新增记录。
如何处理大批量数据的内存溢出与分批提交
当批量数据量极大时,一次性将所有数据加入 PreparedStatement 的批处理队列可能导致内存溢出(OOM)。此时需要采用分批提交策略,即每处理一定数量的数据就执行一次 executeBatch() 和 commit(),然后清空批次。这样既能保持事务的一致性(每个小批次独立事务),又能控制内存占用。

pstmt.clearBatch()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











