5

次のアーキテクチャに基づく MVC Web アプリがあります。

作業単位パターンを使用する Asp.Net MVC2、Ninject、Fluent NHibernate、MySQL。

MySQL へのすべての接続は、SHOW PROCESSLIST クエリ結果のエントリとして表示できるスリープ接続を生成します。

最終的には、アプリ プールの制限を超えて Web アプリをクラッシュさせるのに十分な数の接続が生成されます。

接続が正しく破棄されていないと思われます。

これが事実である場合、これはどこでどのように発生する必要がありますか?

ここに私が使用しているコードのスナップショットがあります:

public class UnitOfWork : IUnitOfWork
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ITransaction _transaction;
    public ISession Session { get; private set; }

    public UnitOfWork(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
        Session = _sessionFactory.OpenSession();
        Session.FlushMode = FlushMode.Auto;
        _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public void Dispose()
    {
        if (Session != null)
        {
            if (Session.IsOpen)
            {
                Session.Close();
                Session = null;
            }
        }
    }

    public void Commit()
    {
        if (!_transaction.IsActive)
        {
            throw new InvalidOperationException("No active transation");
        }
        _transaction.Commit();
        Dispose();
    }

    public void Rollback()
    {
        if (_transaction.IsActive)
        {
            _transaction.Rollback();
        }
    }
}




public interface IUnitOfWork : IDisposable
{
    void Commit();
    void Rollback();
}




public class DataService
{
    int WebsiteId = Convert.ToInt32(ConfigurationManager.AppSettings["Id"]);

    private readonly IKeyedRepository<int, Page> pageRepository;
    private readonly IUnitOfWork unitOfWork;

    public PageService Pages { get; private set; }


    public DataService(IKeyedRepository<int, Page> pageRepository,
        IUnitOfWork unitOfWork)
    {
        this.pageRepository = pageRepository;
        this.unitOfWork = unitOfWork;

        Pages = new PageService(pageRepository);

    }

    public void Commit()
    {
        unitOfWork.Commit();
    }

}


public class PageService
{
    private readonly IKeyedRepository<int, Page> _pageRepository;
    private readonly PageValidator _pageValidation;

    public PageService(IKeyedRepository<int, Page> pageRepository)
    {
        _pageRepository = pageRepository;
        _pageValidation = new PageValidator(pageRepository);
    }

    public IList<Page> All()
    {
        return _pageRepository.All().ToList();
    }

    public Page FindBy(int id)
    {
        return _pageRepository.FindBy(id);
    }
}
4

3 に答える 3

3

あなたの投稿には、UoWが作成されたスコープに関する情報は含まれていません。

一時的な場合。それはまったく処分されません、そしてこれはあなた次第です。

InRequestScopeの場合、GCがHttpContextを収集した後に破棄されます。しかし、最近Ninject Mailing ListでBobに話したように、HttpApplicationのendrequestイベントハンドラーですべてのオブジェクトを解放することが可能です。Ninjectの次のリリースでこれのサポートを追加します。

于 2010-11-15T18:19:53.603 に答える
2

この問題の根本的な原因を調査しました。ここにもう少し情報と可能な解決策があります:

http://blog.bobcravens.com/2010/11/using-ninject-to-manage-critical-resources/

楽しみ。

于 2010-11-18T21:06:51.310 に答える
0

Ninject は、いつ、どこでIDisposables がDisposed になるかについて保証しません。

元の Ninject man からのこの投稿を読む

また、ここを見てみることをお勧めします。これは、さまざまな永続化メカニズムとさまざまなコンテナーで発生しています。重要なことは、UOW の commit/rollback/dispose セマンティクスにいつフックしているのかを制御して把握する必要があることです。偶然または偶然に任せてください(コンベンションは素晴らしいですが)。

于 2010-11-05T17:30:17.867 に答える