0

私はnhibernateで並行性の問題を扱っていますが、正しく行っているかどうかはよくわかりません。バージョンフィールドを使用していますが、トランザクションがコミットされると、バージョンフィールドが別のプロセスによって変更された場合、StaleObjectStateExceptionがスローされると思います。私はこの例外をキャッチしてそのケースを処理し、それは機能しているようです。

しかし、私が疑問に思っているのは、例外がスローされるたびに、NHibernateがlog4net-Logfileにエラーを生成するということです。NHibernateのログレベルをERRORに設定しました。これは、エラーが発生した場合に興味があると思うためです。ただし、同時実行の競合に関するすべてのメッセージには関心がありません。これは、エラーとは見なされないためです。

それで、私が完全に間違ったことをしているのかもしれませんか?例外をキャッチすることで並行性に対処する正しい方法ですか?

更新:これはnhibernateが私のログファイルに入れるものです:

2012-06-21 16:47:30,546エラーNHibernate.Event.Default.AbstractFlushingEventListener:データベースの状態をセッションと同期できませんでした
NHibernate.StaleObjectStateException:行が別のトランザクションによって更新または削除されました(または未保存の値のマッピングが正しくありませんでした):[Delta.FollowUp.Model.CFollowUp#60003]
   bei NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id、Object [] fields、Object [] oldFields、Object rowId、Boolean [] includeProperty、Int32 j、Object oldVersion、Object obj、SqlCommandInfo sql、ISessionImplementor session)in d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs:Zeile2780。
   bei NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id、Object [] fields、Object [] oldFields、Object rowId、Boolean [] includeProperty、Int32 j、Object oldVersion、Object obj、SqlCommandInfo sql、ISessionImplementor session)in d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs:Zeile2692。
   bei NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id、Object [] fields、Int32 [] dirtFields、Boolean hasDirtyCollection、Object [] oldFields、Object oldVersion、Object obj、Object rowId、ISessionImplementor session)in d:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs:Zeile3000。
   bei NHibernate.Action.EntityUpdateAction.Execute()in d:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Action \ EntityUpdateAction.cs:Zeile79。
   de:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Engine \ ActionQueue.cs:Zeile136のbeiNHibernate.Engine.ActionQueue.Execute(IExecutable実行可能ファイル)。
   bei NHibernate.Engine.ActionQueue.ExecuteActions(IList list)in d:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Engine \ ActionQueue.cs:Zeile126。
   bei NHibernate.Engine.ActionQueue.ExecuteActions()in d:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Engine \ ActionQueue.cs:Zeile170。
   bei NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)in d:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Event \ Default \ AbstractFlushingEventListener.cs:Zeile241。
4

2 に答える 2

1

NHibernateエラーをログに記録したくない場合は、NHibernateのロガーを削除するか、FATALレベルに設定するか、何らかの方法で例外をフィルタリングします。

それでも、例外をキャッチし、処理し、再スローし、ログに記録することができます。

于 2012-06-22T00:02:04.877 に答える
1

同時実行の問題がある場合に何をするかは、アプリによって異なります。多くの場合、例外をキャッチして作業単位を再試行するだけで十分ですが、作業単位を定義するのは難しい場合があります。状況によっては、エンティティを再度ロードして変更を再度加えてから保存するだけで十分な場合もありますが、それは実際にはアプリケーションによって異なります。

基本的に、その例外は、別のスレッド/プロセスがデータベース内のエンティティを変更したことを意味するため、それに応じて対応する必要があります。NHibernateは、バージョンフィールドの使用が、変更する行を変更するものが他にないと想定している楽観的同時実行性を意味するため、エラーとしてログに記録します。したがって、何かがそれらの行の1つを変更する場合は、次のようにする必要があります。それを処理します。

于 2012-06-21T17:19:20.963 に答える