2

バッチ更新で楽観的ロックを使用するにはどうすればよいですか?私は使用SimpleJdbcTemplateしており、単一の行に対して、バージョン列の値をインクリメントし、WHERE句にバージョンを含めるupdatesqlをビルドできます。

残念ながら、int[] updated = simpleJdbcTemplate.batchUpdateOracleドライバを使用した場合、結果には行数が含まれません。すべての要素は-2であり、不明な行数を示します。

すべての更新を個別に実行するよりも、これを行うためのよりパフォーマンスの高い方法は他にありますか?これらのバッチには、平均5つのアイテム(のみ)が含まれますが、最大250のアイテムが含まれる場合があります。

4

2 に答える 2

2

ここで考えてみてください-ドライバーのバッチサポートに問題がある場合は、単一のクエリを使用して同じことを達成しようとすることができ、バッチ処理の関連性が低くなります。(ご存じのとおり、バッチ処理とは複数のクエリでレイテンシを回避することですが、1 つのクエリをバッチ処理する場合でもレイテンシは存在します。)

単一のクエリで楽観的な更新を実現する方法は次のとおりです

  • 行の更新に必要な条件を含む一時テーブルを作成し、更新クエリをこのテーブルの結合になるように書き直します。(例: ライブ データの現在のタイムスタンプと一時テーブルのタイムスタンプを外部結合します。) ライブ データのタイムスタンプが更新されていない場合、行は一時テーブルから選択されます。

一時テーブルを選択クエリとして使用できるため、更新される行を見つけて、これを更新クエリとして送信できます。(もちろん、すべてトランザクション内です。)

説明する:

TempUpdateTable
---------------
id,        // id of the row to be updated
timestamp, // timestamp data originally fetched
data1      // data to be updated
data2
dataN

これにより、更新するすべてのデータの ID が得られ、後で参照できるように保存できます。

SELECT d.id FROM TempUpdateTable t JOIN YourData d 
    ON t.id=d.id WHERE t.timestamp=d.timestamp

その後、同じクエリを更新ステートメントで使用できます

UPDATE YourData
SET data=t.data1
SET data=t.data2  //etc...
FROM TempUpdateTable t WHERE t.id IN
  (SELECT d.in FROM TempUpdateTable t JOIN YourData d 
    ON t.id=d.id WHERE d.timestamp=d.timestamp)
于 2010-05-29T05:41:28.120 に答える