0

spring-hibernate アプリケーションがあり、マージを使用してオブジェクトを保存しようとしています。時々、HibernateOptimisticLockingFailureException が発生します。

私はこの問題を解決しようとしました。

2) TimeStamp または Version 列を使用した楽観的ロックのサポートを追加します。3) ID および変更されたデータによってオブジェクトを再度ロードしてから、マージします。4) マージの代わりに保存を使用する。 5) 保存前にオブジェクトをロックし、保存後に解放する。

私は一週間からこの問題を解決しようとしましたが、成功しませんでした.

誰でも助けてもらえますか?

注:hibernate3を使用しています

4

1 に答える 1

1

楽観的ロックを使用すると、断続的なエラーが発生することが予想されます。エラーを処理するコードを追加する必要があります。

楽観的並行コードは、次のように言います。

「私が作業している間、他の誰もこの行に触れないだろうと楽観的にさえ確信しています。このため、行を「悲観的に」ロックする必要はありません。単純に行を読みたいだけの他の人の邪魔になる. 私は愚かではない.変更を書き込む代わりに、エラーを発生させます。」

最終的な結果は、基本的に悲観的なアプローチと同じです。更新は整然と行われています。ただし、ライター以外のユーザーの読み取りパフォーマンスが向上しています。ただし、多くのものが同時に同じ行を編集しようとすると、遅かれ早かれお互いに影響を与えることになります。これが十分に発生すると、ライターは成功するまで再試行し続ける必要があるため、書き込みパフォーマンスがかなり低下する可能性があります。

あなたは言う、

「しかし待ってください! SQL の更新はアトミックです! 2 つの更新が「互いに影響し合う」可能性があるのはどうしてでしょうか?

質問してよかったです。2 人以上の人がまったく同時にレコードを更新するとどうなりますか?をお気軽にお読みください。


すごい!帰ってきたね。話したいことがいくつかあります。

オプティミスティック コンカレンシーの代わりにペシミスティック ロックを使用する必要があるのはどのような場合ですか? 名前がすべてを物語っています。通常は同時更新が発生しないと楽観的である場合は、オプティミスティック同時実行を使用します。一方、同時更新が常に発生することにかなり悲観的である場合は、悲観的ロックを使用して、全員が列に並んで順番を待つようにすることをデータベース サーバーが担当できるようにします。

オプティミスティック コンカレンシー違反が発生した場合、コードはどうすればよいですか? 基本的には、通過するまで再試行するだけです。これを行う最も簡単な方法は、次のようなメッセージをユーザーに表示することです。

「申し訳ありませんが、このレコードは変更されました。変更を保存できませんでした。ページをリロードして、もう一度やり直してください。」

そのため、競合をどのように解決する必要があるかを判断する責任は、ユーザーにあります。欠点は、変更を再入力する必要があることです。

エラーが発生しなくなるまでループで自動的に再試行するコードに夢中になることも、保存された他の変更を調べて変更をインテリジェントにマージしようとするコードに夢中になることもできます。実際にこのようなコードを書き始める必要がある場合は、ペシミスティック ロックを使用したほうがよいという良い兆候かもしれません。

他に何かありますか?Hibernate または NHibernate が例外をスローした場合は、セッションと関連するエンティティを破棄して、新しいエンティティを取得する必要があることを覚えておいてください。彼らは現在、データベースがどのように見えるかについて一貫性のないイメージを持っています。データベース トランザクションをロールバックした可能性がありますが、それらのインメモリ オブジェクトの状態はロールバックされていません。これが Web アプリで、リクエストごとのセッションを実行していて、「ユーザーに「申し訳ありません」と伝える」アプローチを採用している場合、これはユーザーが [保存] ボタンを再度クリックすることで自然に処理されます。

于 2013-11-07T23:06:38.837 に答える