バッチ クエリ クローラー操作の抽象化を作成しようとしています。アイデアは、クエリが実行され、結果セットが取得され、各行に対してコミットまたはロールバックのいずれかの操作が実行されるというものです。要件は、障害の有無に関係なくすべての行が処理され、結果セットが事前にメモリーにロードされないことです。
問題は、ロールバック後に開いている結果セットを維持できないという事実に要約されます。これは仕様によるもので、カーソル保持機能はコミット時に (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 つの異なるスレッドを使用することです。
あなたならどうしますか?