2013-03-20 93 views
1

我正在尋找java併發解決方案,以便我可以使用JDBC批量更新。 BlockingQueue會讓我一次一個項目,我已經有批量更新DAO的方法,但我需要一些解決方案,以便我可以利用JDBC批量更新而不是單個記錄更新。java BlockingQueue和JDBC批量更新

我的工作線程看起來如下:

class DBWorker extends Thread { 
    @Override 
    public void run() { 
     try { 
      while (true) { 
       try { 
        Pair<Long, Status> p = dbQ.take(); 
        //-- 
        orderDao.updateStatus(p.getLeft(), p.getRight()); 
       } catch (InterruptedException e) { 
        log.error(e); 
       } 
      } 
     } catch (Exception e) { 
      log.error(e); 
     } finally { 

     } 
    } 
} 

回答

2

基本上你需要做的是收集多個Pair對象爲Collection,然後傳遞Collection關閉以將執行批量更新的代碼。

你可以嘗試這樣的:

while (true) { 
    Pair<Long, Status> p = dbQ.take(); 
    List<Pair> collectedPairs = new ArrayList(); 
    while (p!=null) { 
     collectedPairs.add(p); 
     p = dbQ.poll(); 
    } 
    orderDao.batchUpdate(collectedPairs); 
} 

但是上面的代碼將主要發佈與一般小尺寸的批次。您可以修改該示例,但要使用定時輪詢方法BlockingQueue.poll(long, TimeUnit)來引入一些延遲並嘗試收集更大的批量大小。

2

BlockingQueue有一個很好的方法,drainTo()基本上把所有的條目,並把它放在一個集合。儘管它沒有阻塞,所以在調用它之前你仍然需要一個take(),這樣它纔不會忙於等待。而不是更新一個和一個,你還需要一個批量更新數據庫的方法。例如:

ArrayList<Pair<Long, Status>> list = new ArrayList<Pair<Long, Status>>(); 
list.add(dbQ.take()); 
//sleep(int n) - if you want to wait for more entries before submitting the batch - otherwise batches will probably be pretty small.. 
dbQ.drainTo(list); 
orderDao.updateInBatch(list); 
+0

+1爲了提示'drainTo',我經常忘記那個好方法。 – 2013-03-20 04:40:13