1

JDBC バッチ更新を使用できるように、Java 同時実行ソリューションを探しています。BlockingQueue は一度に 1 つの項目を許可します。DAO にはバッチ更新のメソッドが既にありますが、単一のレコード更新ではなく 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 {

        }
    }
}
4

2 に答える 2

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)てレイテンシを導入し、より大きなバッチ サイズを収集しようとすることができます。

于 2013-03-20T03:46:42.907 に答える
2

BlockingQueuedrainTo()には、基本的にすべてのエントリを取得してコレクションに入れる素晴らしいメソッドがあります。ブロッキングではありtake()ませんが、ビジーな待機がないように、呼び出す前に が必要になります。いちいち更新するのではなく、DBを一括更新する方法も必要です。例えば:

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);
于 2013-03-20T03:47:45.327 に答える