3

Session が NHibernate によって破棄されたかどうかを確認する方法はありますか?

Session に独自の Finalizer と IDispoable の実装を持つラッパー クラスがありますが、クラスで自分で処理する前に Session が破棄されると、ObjectDisposedException を受け取ることになります。

クリーンアップコードをラップしたくありません

try {
...
}
catch (ObjectDisposedException) { }

しかし、他の方法についてはよくわかりません。Session.IsOpen および Session.IsActive プロパティは、セッションが破棄されたことを確認するための信頼できる情報を提供していないようです。

完全なソースについては、 Assemblaで表示できます。

4

3 に答える 3

1

わかりました、あなたのコードをのぞき見しました。これが正確な問題かどうかはわかりませんが、会話の破棄メソッドから End() を呼び出しています。これにより、再接続が試行され、セッションが破棄されます。これより前に明示的に End() を呼び出した場合は、次のようになります。あなたが得るもの、その呼び出しを避けてください。これは暗黙的に行われるため、セッションが破棄される前にトランザクションをロールバックすることについて心配する必要はないと思います。ざっと見てみましたが、私はあなたの実装が本当に好きだと思います。

于 2009-02-04T21:25:34.197 に答える
0

「それは、私が見た中で最もばかげたことの 1 つであり、処分後も Open プロパティがそのまま維持されています。」

すでに破棄したオブジェクトに、その状態に関する信頼できる情報が含まれているのはなぜですか? 破棄されたセッションを使用しようとするべきではありません。nhibernate がセッションを破棄している場所もわかりません。自分で破棄していないのでしょうか?

于 2009-02-04T20:33:02.680 に答える
0

私は常に、NHibernate のベスト プラクティスは「リクエストごとのセッション」であり、「using」スコープ内にのみ存在する必要があると考えていました。

using(Session session = new Session())
{
}

2 人がセッション/会話を破棄するのを防ぐことをお勧めします。セッションの作成を制御する場合は、例外を防ぐために独自の IsAlreadyDisposed() チェックを実行する独自の ISession 実装でそれをラップできます。それでも、その労力と「予期される例外」、および元のコードを考慮すると、それほど悪くはありません。

また、ファイナライザーの実装に注意することをお勧めします。「Session.Is().InTransaction()」は Session->Transaction になり、ファイナライザーがセッションに到達するまでにセッションが null になる可能性があります。ファイナライザー時に管理された関係をナビゲートすることは、動作することが保証されていません。

于 2009-02-03T22:18:19.973 に答える