首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

大批量 SQL 執行策略:避開事務鎖定的多線程方案

     編輯:程式設計綜合問答

萬條級 UPDATE/INSERT 的性能與並發困境

場景:一次性執行 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();

關鍵點

  1. 頁面刷新不影響後台線程:HTTP 請求結束後,服務端線程池繼續運行。
  2. 異表並行:若更新不同表,可進一步按表分組,減少鎖衝突。
  3. 監控與補償:記錄每批執行狀態,失敗自動重試或人工介入。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved