1

nhibernate と asp.net MVC アプリケーションを使用しています。

httpModule を介して、Session per Request パターンを実装しています。

非常に単純に見えますが、NHibernate Profiler で実行すると、セッションが決して閉じられないことが明確に示されます。

パターンは簡単に見えます...しかし、セッションが閉じない理由がわかりません。

これが私が重要だと思うコードです。

イベント ハンドラを設定します。

    context.EndRequest += new EventHandler(this.context_EndRequest);

ハンドラーでセッションを破棄します

private void context_EndRequest(object sender, EventArgs e)
        {
            netLogHdl.ArchDebug("NHibernateHttpModule.context_EndRequest() ");

            Dispose(0);// we are hitting 2 dbs and thus keep one session for each.
            Dispose(1);

            HttpContextBuildPolicy.DisposeAndClearAll();
        }


private void Dispose(int sessionIndex)
        {
            netLogHdl.ArchStart("NHibernateHttpModule.Dispose", "int sessionIndex=\" + sessionIndex + \")");

            try
            {
                //close the DB session
                string sessManagerName = "";
                string jcdcManager = "JCDC Manager";
                string spamisManager = "Spamis Manager";

                if (sessionIndex == 0)
                    sessManagerName = jcdcManager;
                else
                {
                    sessManagerName = spamisManager;
                }


                ISession oneSession = sessionPerDB[sessionIndex];
                if (oneSession != null)
                {
                    if (sessManagerName == jcdcManager) netLogHdl.ArchDebug(sessManagerName + " oneSession is NOT null");

                    if (oneSession.IsOpen)
                    {
                        // Don't flush - all saves should use transactions and calling Commit does the flush.
                        if (sessManagerName == jcdcManager) netLogHdl.ArchDebug(sessManagerName + " Closing the session");

                        //This will overrite it with the exact same session, if they don't match something weird is going on - EWB
                        oneSession = CurrentSessionContext.Unbind(factoryPerDB[sessionIndex]);
                        oneSession.Close();
                    }
                    else
                    {
                        if (sessManagerName == jcdcManager) netLogHdl.ArchDebug(sessManagerName + " Session is NOT open");
                    }

                    //if ( sessManagerName == jcdcManager ) netLogHdl.ArchDebug( sessManagerName + " Session got Dispose()-ing" );
                    //oneSession.Dispose();
                }
                else
                {
                    if (sessManagerName == jcdcManager) netLogHdl.ArchDebug(sessManagerName + " Session is NULL");
                }

                sessionPerDB[sessionIndex] = null;

            }
            catch (Exception)
            {

                throw;
            }


            netLogHdl.ArchEnd();
        }

誰かが私を正しい方向に向けることができますか? 私が見るべきものは、パターンが正しく実装されていないことですか?

私は困惑しています

ありがとう!

E-

4

2 に答える 2

1

dispose を呼び出す必要があり、切断したり閉じたりしないでください。System.IDisposable 実装オブジェクトは、必ず dispose メソッドを呼び出すか、ブロックを使用して破棄する必要があります。

于 2009-12-02T19:58:20.410 に答える
0

セッション管理に関するBen Day のブログ投稿のコードも参照してください。

于 2009-12-02T23:24:13.613 に答える