2

バッチ クエリ クローラー操作の抽象化を作成しようとしています。アイデアは、クエリが実行され、結果セットが取得され、各行に対してコミットまたはロールバックのいずれかの操作が実行されるというものです。要件は、障害の有無に関係なくすべての行が処理され、結果セットが事前にメモリーにロードされないことです。

問題は、ロールバック後に開いている結果セットを維持できないという事実に要約されます。これは仕様によるもので、カーソル保持機能はコミット時に (ResultSet.HOLD_CURSORS_OVER_COMMIT を使用して) 維持できますが、ロールバックでは維持できません。

JTA/JDBC セマンティクスを使用した単純な実装では、クエリを指定するための拡張ポイントと、各行の実際の操作を指定するための拡張ポイントの 2 つを提供すると、次のようになります。

UserTransaction tx = getUserTransaction();
tx.begin();
ResultSet rs = executeQuery(); //extension point
tx.commit();
while(rs.next()) {
    tx.begin();
    try {
        performOperationOnCurrentRow(ResultSet rs); //extension point
        tx.commit();
        logSuccess();
    }catch(Exception e) {
        tx.rollback();
        logFailure(e);
    }
}

これはそれほど大げさなシナリオではないように思えますが、関連する情報は Web 上でほとんど見つかりませんでした。問題は、これが一般的なフレームワークのいずれかによってエレガントに対処されているかということです。すぐに使えるソリューションが必ずしも必要なわけではありません。このシナリオを処理するための既知の適切な/一般的に受け入れられているアプローチがあるかどうか疑問に思っています。

1 つの解決策は、失敗した行を追跡し、その時点以降にカーソルを再度開くことです。これには通常、いくつかの拡張規則 (順序付けられた結果セット、where 句で最後に失敗した行 ID を使用したクエリなど) を適用する必要があります。

もう 1 つは、クエリと行操作に 2 つの異なるスレッドを使用することです。

あなたならどうしますか?

4

1 に答える 1

1

これは数年前から回答されていないので、続けて自分で回答します。

私たちが考え出した解決策は、プロセス ( と呼ばれる) が(SQL に限らずBatchProcess) を実行し、その結果を並行 に追加するという考えに基づいています。は、のエントリを消費し、そのエントリを入力として使用するを実行する多数のオブジェクト (新しいスレッドで実行) を生成します。各実行は、単一の作業単位として実行されます。基礎となるトランザクション マネージャーは JTA 実装です。QueryQueueBatchProcessQueueProcessorQueueOperationOperation

少し時代遅れですが、ある時点での実装はこれでしたhttps://bo2.googlecode.com/svn/trunk/Bo2ImplOpen/main/gr/interamerican/bo2/impl/open/runtime/concurrent/BatchProcess.java

そのレポのどこかに BatchProcess の監視と管理のための GUI さえあります ;)

免責事項:この男は、この設計と実装に多くのことをしていましたhttps://stackoverflow.com/users/2362356/nakosspy

Batch Process オブジェクトの UML ダイアグラム

于 2014-08-01T12:14:29.043 に答える