2010-11-05 9 views
5

Ho un'applicazione web MVC che si basa sulla seguente architetturaAsp.Net MVC UNitOfWork e MySQL e letto Connessioni

Asp.Net MVC2, Ninject, Ottima NHibernate, MySQL che utilizza un'unità di modello di lavoro.

Ogni connessione a MySQL genera una connessione di sospensione che può essere vista come una voce nei risultati della query SHOW PROCESSLIST.

Alla fine verranno generate sufficienti connessioni per superare il limite del pool di applicazioni e arrestare in modo anomalo l'app Web.

Ho il sospetto che le connessioni non vengano smaltite correttamente.

Se questo è il caso, dove e come dovrebbe accadere?

Ecco un'istantanea del codice che sto usando:

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

risposta

3

Il tuo post non fornisce alcuna informazione in quale ambito vengono creati gli UoW.

Se è temporaneo. Non sarà smaltito affatto e questo dipende da voi.

In InRequestScope verrà eliminato dopo che il GC ha raccolto HttpContext. Ma come ho detto recentemente a Bob nello Ninject Mailing List è possibile rilasciare tutti gli oggetti nel gestore di eventi di richiesta finale di HttpApplication. Aggiungerò il supporto per questo nella prossima versione di Ninject.

+0

era me che era in contatto con Bob Cravens dell'eccellente blog.bobcravens.com e ora sto usando EndRequest + = delegato { IUnitOfWork UOW = Kernel.Get (); uow.Dispose(); }; –

0

Ninject non fornisce alcuna garanzia circa quando e dove i tuoi IDisposable s saranno Dispose d.

Leggi questa post from the original Ninject man

Vorrei anche suggerire di dare un'occhiata qui intorno, questo è venuto in su per vari meccanismi di persistenza e contenitori vari - la cosa fondamentale è che si ha bisogno di prendere il controllo e sapere quando si sta agganciando nella UOW di commit/rollback/dispose semantica e non lasciarla al caso o alla coincidenza (sebbene Convention sia grande).