Java 使用線程池分批插入或者更新數據


  需求:在開發業務報表時,需要從MySQL數據庫讀取數據后進行操作,然后寫入數據庫,使用定時任務跑批。

  分析:①兼顧性能,②  MySQL沒有Oracle那么方便、強大的存儲過程。綜上所述,使用線程池以分批提交的方案來插入MySQL數據庫,對於更新操作、在Java端進行分頁等的操作,本方案也支持。代碼如下:

 1     private void batchDeal(List data, int batchNum) throws InterruptedException {  2         int totalNum = data.size();  3         int pageNum = totalNum % batchNum == 0 ? totalNum / batchNum : totalNum / batchNum + 1;  4         ExecutorService executor = Executors.newFixedThreadPool(pageNum); 
5
try { 6 CountDownLatch countDownLatch = new CountDownLatch(pageNum); 7 List subData = null; 8 int fromIndex, toIndex; 9 for (int i = 0; i < pageNum; i++) { 10 fromIndex = i * batchNum; 11 toIndex = Math.min(totalNum, fromIndex + batchNum); 12 subData = data.subList(fromIndex, toIndex); 13 ImportTask task = new ImportTask(subData, countDownLatch); 14 executor.execute(task); 15 } 16 // 主線程必須在啟動其它線程后立即調用CountDownLatch.await()方法, 17 // 這樣主線程的操作就會在這個方法上阻塞,直到其它線程完成各自的任務。 18 // 計數器的值等於0時,主線程就能通過await()方法恢復執行自己的任務。 19 countDownLatch.await(); 20 logger.info("數據操作完成!可以在此開始其它業務"); 21 } finally { 22 // 關閉線程池,釋放資源 23 executor.shutdown(); 24 } 25 } 26 27 class ImportTask implements Runnable { 28 private List list; 29 private CountDownLatch countDownLatch; 30 31 public ImportTask(List data, CountDownLatch countDownLatch) { 32 this.list = data; 33 this.countDownLatch = countDownLatch; 34 } 35 36 @Override 37 public void run() { 38 if (null != list) { 39 // 業務邏輯,例如批量insert或者update 40 logger.info("現在操作的數據是{}", list); 41 } 42 // 發出線程任務完成的信號 43 countDownLatch.countDown(); 44 } 45 }

  在第1行中,List data表示傳入的數據,batchNum表示每一次處理的數量,例如500條等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM