2010-11-05 10 views
5

Mam aplikację MVC, która jest oparta na następującej architekturzeAsp.Net MVC UNitOfWork i MySQL i spanie Połączenia

Asp.Net MVC2, Ninject, Fluent NHibernate, MySQL, która wykorzystuje jednostkę wzór pracy.

Każde połączenie z MySQL generuje połączenie uśpienia, które może być postrzegane jako wpis w wynikach zapytania POKAŻ LICę PROCESOWĄ.

W końcu spowoduje to nawiązanie wystarczającej liczby połączeń, aby przekroczyć limit puli aplikacji i zawiesić działanie aplikacji internetowej.

Podejrzewam, że połączenia nie są prawidłowo ułożone.

Jeśli tak, to gdzie iw jaki sposób należy to zrobić?

Oto migawki z kodem, który używam:

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); 
    } 
} 

Odpowiedz

3

Twój wpis nie zawiera żadnych informacji, w jakim zakresie tworzone są UU.

Jeśli jest przejściowy. To nie będzie w ogóle wyrzucone, a to zależy od ciebie.

W przypadku InRequestScope zostanie on usunięty po odebraniu przez GC HttpContext. Ale jak powiedziałem Bobowi ostatnio w Ninject Mailing List, możliwe jest zwolnienie wszystkich obiektów w procedurze obsługi zdarzeń żądania końcowego HttpApplication. Dodam obsługę tego w następnej wersji programu Ninject.

+0

był sam, który był w kontakcie z Bobem Cravens doskonałego blog.bobcravens.com i jestem teraz za pomocą EndRequest + = delegata { IUnitOfWork UOW = Kernel.Get (); uow.Dispose(); }; –

0

Ninject nie udziela żadnych gwarancji co, kiedy i gdzie IDisposable s będzie Dispose d.

Czytaj ten post from the original Ninject man

Chciałbym również zasugerować zaglądając tu ta ma pochodzić z różnych mechanizmów utrwalania i różnych pojemników - kluczową sprawą jest konieczne, by przejąć kontrolę i wiedzieć, kiedy jesteś podpinania w przypisaniu/wycofywaniu/usuwaniu semantyki UOW i nie pozostawiaj tego przypadkowi lub koincydentowi (choć Konwencja jest świetna).