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

Your post does not give any information in which scope UoW's are created.

If it is transient. It won't be disposed at all and this is up to you.

In case of InRequestScope it will be disposed after the GC has collected the HttpContext. But as I told Bob recently in the Ninject Mailing List it is possible to release all objects in the end request event handler of the HttpApplication. I'll add support for this in the next release of Ninject.

于 2010-11-15T18:19:53.603 回答
2

I did some investigation into the root cause of this problem. Here is a bit more information and possible solutions:

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

Enjoy.

于 2010-11-18T21:06:51.310 回答
0

IDisposableNinject 不保证您的 s 将在何时何地出现Dispose

阅读原始 Ninject 人的这篇文章

I'd also suggest having a look around here, this has come up for various persistence mechanisms and various containers - the key thing is you need to take control and know when you're hooking in the UOW's commit/rollback/dispose semantics and not leave it to chance or cooincidence (though Convention is great).

于 2010-11-05T17:30:17.867 回答