0

全て、

エラーが発生した場合、セッション オブジェクト (ISession またはその ISessionImplementor) から判断できますか? または、セッションでエラーが発生したときに呼び出される偶数ハンドラーをフックすることは可能ですか?

コードをtry/catchでラップし、セッションをすぐに破棄することにより、セッションを処理するパターンをよく知っています。ただし、私の場合は、現在のスコープで実行されている DAO に休止状態セッションを渡すセッション スコープに相当するものを実装しました。休止状態のセッションを提供すると、クライアント コードはそれを単に永続的な操作を実行するために使用します。セッション クリーンアップの責任をクライアントに負わせたくありません。これはセッション スコープの責任です。例を次に示します。

using (new SessionScope(SessionHelper.OpenSession()))
{
    // do read/write etc.
    // ex:
    mydao.MakePersistent(someEntity);  // <-- an error can occur here
} // implicit flush/clean up, BUT in order to do this correctly I have to know if the session in the scope has no errors!

ご覧のとおり、SessionScope は IDisposable を実装し、そこでフラッシュ、tx.Commit()、破棄などのセッションのファイナライズを行います。しかし、エラーが発生した場合、セッションをフラッシュできません!

回避策の 1 つは、生の休止状態セッションを提供するのではなく、セッション操作を実行するためのメソッドを備えたラッパー オブジェクトを提供することです。これにより、任意の操作を try/catch でラップし、エラーが発生した時期を知ることができます。あなたが私に尋ねると、それはばかげた回避策です。

もう 1 つのオプションは、すべての DAO がエラーが発生したことをセッション スコープに通知することです。つまり、すべての DAO メソッド (catch ブロック内) は、セッション スコープが定義されているかどうかを確認する必要があり、定義されている場合は、セッションの失敗に責任があります。 (scope.FailSession(session);) それははるかに優れていますが、すべての DAO で宗教的に行う必要があり、忘れると、エラーが発生したセッションで session.Flush() を呼び出して、セッション スコープが誤動作します。

Oskar B. のコメントのおかげで、ACID プロパティを持つ必要があるロジックや、持続性に関係のない例外のリスクがあるロジックには、トランザクション ベースのアプローチを使用する必要があります。修正されたソリューションは次のとおりです。

using (var txScope = new TransactionScope(SessionHelper.OpenSession()))
{
     Customer cust = mydao.getCustomer();
     Order order = mydao.getOrder(cust);
     // modify order, etc. (an error may occur at any time within this scope)
     txScope.VoteCommit();           
} // if we voted commit, it will flush/commit otherwise it will rollback 
4

2 に答える 2

0

通常、トランザクションはセッションとは別にします。これは、アプリケーションコードでトランザクションのコミットを確認する必要があるためです(例外がない場合は、行tx.Commit()に到達します)。セッションスコープのDispose()は、単にsession.Dispose()になります。

1つの方法は、scope.FailSession()のアイデアをscope.CompleteSession()に置き換えることです。これは上記に類似しています。忘れると何も保存されず、問題がすぐに明らかになります。

多くの場合、セッションは、特定のDAOではなく、はるかに広い範囲で処理されます。これにより、単一のトランザクション内で「ユーザー要求」の作業全体を実行することが困難になるためです。通常、例外が発生すると、残りのドメインロジックとその他の「アプリケーションコード」がスキップされます。したがって、実際の例外処理とセッション処理は、コードの一部にのみ存在する必要があります。

于 2013-03-18T06:29:11.153 に答える
0

唯一の方法は、例外を処理して対処することです。

于 2013-03-22T01:11:15.073 に答える