2016-08-03 8 views
0

Web API/MVCアプリケーションのセッションを管理するためにninjectを使用しています。コードは次のとおりです。Ninject 3.2 OnDeactivationがWeb APIを起動しない

Bind<ISession>().ToMethod(c => c.Kernel.Get<ISessionFactory>().OpenSession()) 
      .InRequestScope() 
      .OnActivation(s => s.BeginTransaction()) 
      .OnDeactivation((s) => 
      { 
       try 
       { 
        s.Transaction.Commit(); 
       } 
       catch (Exception e) 
       { 
        s.Transaction.Rollback(); 
       } 

       s.Close(); 
       s.Dispose(); 
      }); 
    } 

OnActivationコードが正しく呼び出されます。セッションが挿入されると、トランザクションが開始されます。ただし、要求が完了すると、ondeactivationは呼び出されません。したがって、私はデータベースから物事を照会することはできますが、変更をコミットすることはできません(トランザクションを他の場所でコミットしない限り)。

なぜOnDeactivationが呼び出されていないのかわかりません - 私は自分の鼻腔の設定で何かを見逃していますか? OnDeactivation常にが呼び出されますのでOnDeactivationCommitを呼び出す

答えて

0

は、例外は、ビジネスレイヤ内からスローされた場合でも、本当に悪い考えです。エラーが発生した場合、トランザクションをコミットしたくはありません。

異なるレベルでコミットすることを検討する必要があります。 This q/aではこれについてより詳しく説明し、この問題を解決する方法を示しています。

また、コードが過度に冗長であることにも注意してください。 Disposeに電話をした場合は、Closeに電話する必要はなく、コミットされていないトランザクションでDisposeとコールすると、トランザクションは自動的にロールバックされます。プラグを抜くこともできます。データベースはコミットされていないトランザクションを自動的にロールバックします。言い換えれば、あなたは簡単に次のようにコードを簡素化することができます:あなたが説明hereとしてOnePerRequestHttpModuleを利用するとき、あなたもDisposeを削除することができます

.OnDeactivation((s) => 
{ 
    try 
    { 
     s.Transaction.Commit(); 
    } 
    finally 
    { 
     s.Dispose(); 
    } 
}); 

。これは、にさらにコードを削減:

.OnDeactivation(s => s.Transaction.Commit()); 

しかし、再び、OnDeactivationは絶対にコミットする間違った場所です。

+0

が表示されています - コミットは他の場所に移動します。私の問題は、オンデアクチベーションが(今まで)呼び出されていないということでした。 – Bonnotbh

+1

@Bonnotbh OnDeactivationと廃棄は通常、Ninjectでは非確定的です。 NinjectはGCによってゴミが収集された後にクリーンアップします。これは、データベース接続では実行できないことがよくあります。 – Steven

関連する問題