問題タブ [staleobjectstate]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
hibernate - Hibernate とのトランザクション競合を検出する方法は?
hibernate-entitymanager で Hibernate 2.6 を使用しています。オブジェクトで 2 つのトランザクションが競合する状況をキャッチして処理しようとしています。何が起こるかは次のとおりです。
2 つのスレッドが @Version フィールドを持つ単一のオブジェクトを更新しています。コミット競合を失ったスレッドは、フラッシュ時に StaleObjectStateException をログに記録します。例外はスローされず、ログに記録されるだけです。その時点で、トランザクションはロールバックのみとマークされていると思います。
その後、スレッドがコミットを実行しようとすると、RollbackException で失敗します。トランザクションがロールバックされる理由をコードで見つける方法が見つかりませんでした。
コードでそのような状況をキャッチして処理する方法はありますか? 基本的には StaleObjectStateException をキャッチしたいのですが、問題はスローされないことです。
更新:鳥瞰図から達成しようとしているのは次のとおりです。
JBoss で J2EE アプリケーションを実行しています。内部タイマーによって呼び出されるサービスと、UI から呼び出されるサービスがいくつかあります。また、重要なエンティティが 1 つあります。データの不整合が発生する可能性があるため、異なるスレッドがそのエンティティ クラスのオブジェクトを同時に更新できないようにする必要があります。これが、私が楽観的ロックを実装している理由です。
楽観的ロックの問題が発生した場合、私はこの状況を一般的に処理しようとしています。私はそれを非常に高いレベルでキャッチし、有効なユーザー メッセージを表示したいと考えています (私の場合、最高レベルは RestEasy の ExceptionMapper です)。問題は、RollbackException をキャッチした時点ですでに手遅れであることです。
手動でフラッシュしません。ほとんどの EJB は CMT を使用しており、セッションは自動的にフラッシュされます。
design-patterns - ステイル状態とは?
ウィキペディア ( http://en.wikipedia.org/wiki/Object_pool )でオブジェクト プール パターンについて読んでいて、 「危険なほど古い状態」について言及しています。
「古い」状態とは正確には何ですか?状態がフィールドやプロパティなどの変数/データであることは知っていますが、古いまたは危険なほど古いとはどういう意味ですか?
asp.net-mvc - asp.net mvcアプリケーションでStaleObjectStateExceptionを処理する場所は?
Session per Request パターンを使用しています。トランザクションは自動的に管理されます。
StaleObjectStateException を簡単に処理し、特定のビューを表示するにはどうすればよいですか?
java - Hibernate-クエリでStaleObjectStateExceptionが発生する可能性はありますか?
StaleObjectStateException
最初のクエリと2番目のクエリの間の異なるセッション内での同時更新によってそのクエリの結果データが変更された場合、1つのtx内で同じクエリを2回実行すると、Hibernateでを取得できますか?
このシナリオでは、すべてのエンティティで楽観的同時実行制御を使用しています。
こんな感じです。
スレッド1:トランザクションが開始
されますスレッド1:クエリが実行されて取得されます。つまり、key = 4711の順序
スレッド2:キー4711の同じ順序が取得され、変更され、2番目のスレッドでコミットされます
スレッド1:クエリが再度実行され、戻る必要がありますkey=4711で注文する
StaleObjectStateException
2番目のクエリでThread-1を取得しますか?
ご協力いただきありがとうございます!
トーマス
java - StaleObjectstateException行はによって更新または削除されました
hibernateを使用するSpringFrameworkに基づくWebアプリケーションのコントローラーでこの例外が発生します。私はこれに対抗するために多くの方法を試みましたが、それを解決することができませんでした。
コントローラのメソッドではhandleRequestInternal
、送信アクションがない限り、主に「読み取り」のためにデータベースに対して呼び出されます。私はSpring'sSessionを使用してきましたが、移動しましたがgetHibernateTemplate()
、問題はまだ残っています。
基本的に、これはデータベースへの2回目の呼び出しで、この例外をスローします。あれは:
1)getEquipmentsByNumber(number)
{最初に、プロパティのリストがあり、各プロパティに値のリストがある「番号」に基づいて、機器がDBからフェッチされます。これらの値(プリミティブオブジェクトの文字列)をループして変数に読み込みます)
2)getMaterialById(id)
{idに基づいてマテリアルをフェッチします}
2番目の呼び出しは、おそらく「フラッシュ」するセッションを行っていることを理解していますが、私はオブジェクトを「読み取っている」だけです。何も変更されていない場合、2番目の呼び出しがEquipmentプロパティで古いオブジェクト状態の例外をスローするのはなぜですか。 ?
ビューに渡すオブジェクトでLazyExceptionsが発生するため、呼び出し後にキャッシュをクリアできません。
私はこれを読みました: https ://forums.hibernate.org/viewtopic.php?f = 1&t = 996355&start = 0 しかし、提供された提案に基づいて問題を解決できませんでした。
この問題を解決するにはどうすればよいですか?任意のアイデアや考えをいただければ幸いです。
更新:
私が今テストしたのはgetEquipmentsByNumber()
、プロパティのリストから変数を読み取った後の関数で、これを行うことです:getHibernateTemplate().flush();
そして今、例外は、マテリアルをフェッチするための呼び出しではなく、この行にあります(つまりgetMaterialById(id)
)。
更新: flushを明示的に呼び出す前に、セッションキャッシュからオブジェクトを削除して、古いオブジェクトがキャッシュに残らないようにします。
さて、これを行った後、問題はDBからの次のフェッチに移りました。メソッドに同期済みのラベルを付け、内容を読み終えたらすぐにオブジェクトを削除する必要があると思います。あまり良く聞こえません。
更新:
メソッドhandleRequestInternal
を「同期」しました。エラーは消えました。もちろん、最善の解決策ではありませんが、何をすべきか!handleRequestInternal
現在のセッションを閉じて、新しいセッションを開くことを試みました。ただし、アプリの他の部分が正しく機能しなくなる可能性があります。ThreadLocal
どちらも機能しなかったものを使おうとしました。
hibernate - grails で、更新直後に StaleObjectStateException が発生するのはなぜですか?
次のようなコードを取得しました。
取得と更新にもかかわらず、保存の実行時に「org.hibernate.StaleObjectStateException: 別のトランザクションによって行が更新または削除されました (または未保存値のマッピングが正しくありませんでした)」というメッセージが表示されることがあります。
このメソッドを複数のセッションで同時に実行し始めると発生します。しかし、その後、トランザクション 1 は確実に終了し、このコードはトランザクション 2 に対して再度実行されますが、それでも失敗します! (トランザクション サービスを使用して、楽観的ロックが原因でトランザクションが失敗したときにトランザクションを再実行しています。こちらを参照してください)。
DB から「新しい」バージョンを取得しても、どうすればよいのでしょうか?
nhibernate - NHibernateはバージョンとしてマップされたプロパティをどのように更新する必要がありますか
流暢なNHibernateを使用して、を使用してマップされたクラスのプロパティがありますVersion
オブジェクトを保存すると、予想どおりにVersionプロパティがデータベースに増分されますが、オブジェクトのプロパティの値は時々変更されるだけのようです。
問題は、それが1のままで、さらに変更を加えて再度保存すると、StaleObjectStateExceptionが発生することです。
奇妙なことに、正常に動作し、item.Version値が正しくインクリメントされることがありますが、そうでない場合とそうでない場合の違いがわかりません。
検索してみましたが、これに関するドキュメントが見つからないようです。NHibernatesが期待する動作がバージョンマッピングで何であるかを誰かが説明できますか?
[NHibernateバージョン2.1.2]
hibernate - Spring 宣言型トランザクション管理での Hibernate 例外の処理
Spring+Hibernate+Struts アプリケーションに PROPAGATION_REQUIRED 宣言型トランザクション管理アプローチを使用しました。StaleObjectException
サービス呼び出しが行われた場所 (トランザクションが開始された場所) で (意図した) をキャッチできます。サービス メソッドには、更新を実行するネストされた呼び出し Foo1、Foo2、Foo3 があります。これらのメソッドで例外をキャッチしたい。どうすればそうできますか?代替手段または回避策はありますか?
hibernate - エンティティの削除時に StaleObjectStateException を回避する
同時に(Spring)トランザクションサービスに入る2つの同時スレッドがあります。
Hibernate を使用して、サービス メソッドはいくつかのエンティティをロードして処理し、エンティティを見つけて DB から削除します。擬似コードは次のとおりです。
2 つのスレッドが同時に同じパラメーターを渡す場合、両方が同じエンティティを「検索」し、両方が を呼び出しますdelete
。org.hibernate.StaleObjectStateException
そのうちの 1 つは、セッションが閉じているときに をスローして失敗します。
例外がスローされずに、両方のスレッドがエンティティを返すことを望みます。これを達成するために、次のように、エンティティを削除する前に(「select ... for update」で)ロックしようとしました:
load()
代わりに使用するのget()
は、hibernate API によると、既にセッションにある場合は get がエンティティを返し、load はエンティティを再読み取りする必要があるためです。
2 つのスレッドが同時に上記の方法に入ると、そのうちの 1 つがロック ステージをブロックし、最初のスレッドがトランザクションを閉じると、2 番目のスレッドが呼び出されてorg.hibernate.StaleObjectStateException
. なんで?
ロックされたロードが null を返さないのはなぜですか? どうすればこれを達成できますか?
nhibernate - NHibernate StaleObjectStateException の後にオブジェクト グラフをどのようにマージするのですか?
マージされたコピーを保存するために StaleObjectStateException がスローされた後、オブジェクトを結合しようとしています。
当社の環境状況は次のとおりです。
- リスト項目
- マルチユーザーシステム
- WPF デスクトップ アプリケーション、SQL Server 2008 データベース
- NHibernate 3.1.0.4000、FluentNHibernate 1.2.0.712
- グローバルで長期にわたる NHibernate セッション [今のところ. プレゼンターごとのセッションが推奨されるパターンであることは理解していますが、現時点ではプロジェクト スケジュールに変換する時間がありません。]
- トップダウン保存とプロパティ ナビゲーション (つまり、トップレベル オブジェクト (ここでは親と呼ばれます) をドメイン グラフに保存します)
- ほとんどの場合、.Cascade.AllDeleteOrphan() が使用されます。
- ユーザーは、ドメイン グラフ内のいくつかのオブジェクトを排他的に所有しますが、親の所有権を共有します。
- Children オブジェクトのナビゲーション プロパティは存在しません。
- すべてのクラスには、数値の ID フィールドと数値のバージョン フィールドがあります。
使用事例:
- ユーザー 1 がアプリケーションを起動し、親を開きます。
- ユーザー 2 がアプリケーションを起動し、親を開きます。
- ユーザー 2 が子 (ここでは C2) を追加します。
- ユーザー 2 が親を保存します。
- ユーザー 1 が子 (ここでは C1) を追加します。
- ユーザー 1 が親を保存します。
- ユーザー 1 は StaleObjectStateException を受け取ります (当然のことです)
例外を適切に処理したいと考えています。ユーザーは親の所有権を共有しているため、ユーザー 1 は正常に保存でき、新しい子とユーザー 2 の子の両方で親を保存できます。
Ayende ( http://msdn.microsoft.com/en-us/magazine/ee819139.aspx )によると、SOSE がスローされると、次のようになります。
NHibernate では、セッションから例外がスローされると、そのセッションが未定義の状態に移行するため、セッションとその読み込まれたエンティティは乾杯します。そのセッションまたは読み込まれたエンティティは使用できなくなります
C1 には、現在では役に立たないセッションによって ID とバージョン番号が既に割り当てられています。(そうでなかったらよかったのに。)
ISession.Merge() と ISession.Refresh() の使用を組み合わせて、 C1 と C2 の両方を持つ新しく保存された Parent を取得するにはどうすればよいでしょうか?
私たちは多くの難解な順列を試しましたが、どれも完全には機能しませんでした。通常、「行が別のトランザクションによって更新または削除された (または保存されていない値のマッピングが正しくなかった)」か、ODBC レベルでの実際の ID の衝突のいずれかです。
現時点での私たちの理論:
- C1 のバージョン番号をリセットします (「保存されていない値のマッピングが正しくない」ことを防ぐため)
- 新しいセッションを取得する
- newSession.Refresh(C1);
- newParent = newSession.QueryOver[...]
- newParent.Add(C1);
- newSession.SaveOrUpdate(newParent)
ただし、すべてのドキュメントは、newSession.Merge で十分であることを示唆しています。
研究として使用されるその他の投稿:
流暢な NHibernate 初心者: 別のトランザクションによって行が更新または削除され
た
StaleObjectstateException 行は、
変更されたプロパティのみを保存するように NHibernate に指示する方法
によって更新または削除されました
。