我正在寻找java并发解决方案,以便我可以使用JDBC Batch更新。 BlockingQueue会给我一个项目,我已经有DAO批量更新的方法,但我需要一些解决方案,以便我可以利用JDBC Batch更新而不是单个记录更新。
我的工作线程看起来如下:
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 {
}
}
}
答案 0 :(得分: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)
来引入一些延迟并尝试收集更大的批量大小。
答案 1 :(得分: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);