場景:一次性執行 1 萬條更新/插入語句,若包裹在單一事務中:
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 單事務執行 | 原子性強,代碼簡單 | 長事務鎖表,並發差 | 數據量小、離線批處理 |
| 拆分多事務 | 釋放鎖更頻繁 | 需自行管理一致性,代碼複雜 | 業務允許部分失敗 |
| 多線程非事務 | 並行度高,不阻塞讀 | 無 ACID 保障,需冪等設計 | 日志導入、數據同步等非核心業務 |
// 1. 將 SQL 切分為批次(如每批 500 條)
List> batches = splitSqlList(allSql, 500);
// 2. 線程池併發執行
ExecutorService pool = Executors.newFixedThreadPool(4);
for (List batch : batches) {
pool.submit(() -> {
Connection conn = dataSource.getConnection();
try {
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
for (String sql : batch) stmt.addBatch(sql);
stmt.executeBatch();
conn.commit();
} catch (Exception e) {
conn.rollback();
// 記錄失敗批次,重試或告警
} finally {
conn.close();
}
});
}
pool.shutdown();