1

を使用して、MS SQL データベースからデータのサブセットを選択していPreparedStatementます。結果セットを繰り返しながら、行も更新したいと考えています。現時点では、次のようなものを使用しています。

prepStatement = con.prepareStatement(
                    selectQuery,
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_UPDATABLE);


 rs = prepStatement.executeQuery();

while(rs.next){
rs.updateInt("number", 20)
rs.updateRow();
}

データベースは正しい値で更新されますが、次の例外が発生します。

Optimistic concurrency check failed. The row was modified outside of this cursor.

私はそれをグーグルで検索しましたが、問題に関するヘルプを見つけることができませんでした.

この例外を防ぐにはどうすればよいですか? または、プログラムは私がやりたいことを実行するので、それを無視できますか?

4

2 に答える 2

2

レコードは、(カーソルを介して) データベースから取得された瞬間と、それを保存しようとした瞬間との間に変更されています。number列がレコードの残りの部分とは無関係に、または既に列を他の値に設定している他のプロセスとは無関係に安全に更新できる場合は、次のnumberことを実行したくなるかもしれません。

con.execute("update table set number = 20 where id=" & rs("id") )

ただし、競合状態は持続し、変更は別のプロセスによって上書きされる可能性があります。

最善の戦略は、例外を無視し(レコードは更新されませんでした)、おそらく失敗したレコードを (メモリ内の) キューにプッシュしてから、失敗したレコードに対して2 回目のパスを実行します (条件を再評価し、必要にquery応じて更新します -失敗number <> 20queryたレコードがなくなるまで繰り返します。最終的にはすべての記録が更新されます。

于 2009-03-06T14:17:48.973 に答える
0

更新する行を正確に知っていると仮定すると、私はそうします

  • AUTOCOMMIT を OFF に設定します
  • ISOLATION レベルを SERIALIZABLE に設定
  • SELECT row1, row1 FROM table WHERE somecondition FOR UPDATE
  • 行を更新します
  • 専念

これは、悲観的ロックによって実現されます (DB で行ロックがサポートされていると仮定すると、動作するはずです)。

于 2009-07-09T04:24:51.443 に答える