2010-07-01 3 views
0

J'utilise un HttpModule pour gérer mes sessions et transactions NHibernate. J'ai beaucoup de pages qui sont très grincheuses sur les transactions qui ne démarrent pas correctement sur ma boîte IIS6 mais pas quand je les lance localement, en particulier lorsque j'essaie d'appeler Commit() sur les transactions pendant un PostBack pour actualiser les données avec de nouvelles données mises à jour. Ces erreurs ne se produisent pas lorsque je débogue le code localement.Sessions/transactions NHibernate agissant différemment sur le serveur de débogage IIS6 et Visual Studio 2008

Les fichiers web.config pour le serveur local et le serveur sont les mêmes.

Y a-t-il une configuration sur le serveur qui pourrait provoquer des différences de comportement avec le module sur IIS que mon serveur de débogage VS local gère correctement?

Le code du module ressemble à ceci:

public class NHibernateSessionModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += BeginTransaction; 
     context.EndRequest += CommitAndCloseSession; 
    } 

    private static void BeginTransaction(object sender, EventArgs e) 
    { 
     if (HttpContext.Current.Request.RawUrl.Contains(".aspx")) 
     { 
      NHibernateSessionManager.Instance.InitSessionFactory(); 
      NHibernateSessionManager.Instance.BeginTransaction(); 
     } 
    } 

    private static void CommitAndCloseSession(object sender, EventArgs e) 
    { 
     if (HttpContext.Current.Request.RawUrl.Contains(".aspx")) 
     { 
      try 
      { 
       NHibernateSessionManager.Instance.FlushSession(); 
       NHibernateSessionManager.Instance.CommitTransaction(); 
      } 
      finally 
      { 
       NHibernateSessionManager.Instance.CloseSession(); 
      } 
     } 
    } 

    public void Dispose() { } 
} 

Le code manager concerné est la suivante:

private void InitSessionFactory() 
    { 
     if (sessionFactory != null) 
     { 
      return; 
     } 

     var cfg = new Configuration(); 

     // The following makes sure the the web.config contains a declaration for the HBM_ASSEMBLY appSetting 
     if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["HBM_ASSEMBLY"])) 
     { 
      throw new ConfigurationErrorsException(
       "NHibernateManager.InitSessionFactory: \"HBM_ASSEMBLY\" must be " + 
       "provided as an appSetting within your config file. \"HBM_ASSEMBLY\" informs NHibernate which assembly " + 
       "contains the HBM files. It is assumed that the HBM files are embedded resources. An example config " + 
       "declaration is <add key=\"HBM_ASSEMBLY\" value=\"MyProject.Core\" />"); 
     } 

     // Don't make session factories for foundations that share a database 
     string hibernateString = BaseAccess.GetHibernateConnectionString(); 


     cfg.AddAssembly(ConfigurationManager.AppSettings["HBM_ASSEMBLY"]); 
     cfg.SetProperty("connection.connection_string", hibernateString); 
     sessionFactory = cfg.BuildSessionFactory(); 
    } 

    public void BeginTransaction() 
    { 
     if (threadTransaction == null || 
      threadTransaction.WasCommitted || 
      threadTransaction.WasRolledBack || 
      !threadTransaction.IsActive) 
     { 
      threadTransaction = GetSession().BeginTransaction(); 
     } 
    } 

    public ISession GetSession() 
    { 
     if (null == sessionFactory) 
     { 
      InitSessionFactory(); 
     } 

     if ((threadSession == null || !threadSession.IsOpen) && null != sessionFactory) 
     { 
      threadSession = sessionFactory.OpenSession(); 
     } 

     return threadSession; 
    } 

    private void FlushSession() 
    { 
     if (null != threadSession && threadSession.IsOpen) 
     { 
      threadSession.Flush(); 
     } 
    } 

    public void CommitTransaction() 
    { 
     try 
     { 
      if (threadTransaction!= null && !threadTransaction.WasCommitted && !threadTransaction.WasRolledBack && threadTransaction.IsActive) 
      { 
       threadTransaction.Commit(); 
       threadTransaction = null 
      } 
     } 
     catch (HibernateException) 
     { 
      RollbackTransaction(); 
      throw; 
     } 
    } 

    public void RollbackTransaction() 
    { 
     try 
     { 
      if (threadTransaction != null && !threadTransaction.WasCommitted && !threadTransaction.WasRolledBack && threadTransaction.IsActive) 
      { 
       threadTransaction.Rollback(); 
      } 
     } 
     finally 
     { 
      CloseSession(); 
     } 
    } 

    private void CloseSession() 
    { 
     if (threadSession != null && threadSession.IsOpen) 
     { 
      threadSession.Close(); 
     } 
    } 
+0

Quels sont les messages d'erreur? –

+0

Habituellement, il est "Transaction pas démarré avec succès" – mikeschuld

Répondre

2

Une estimation parce que le code complet n'est pas inclus: Vous pouvez stocker la session dans le fil et le filetage se comporte différemment? Vous devriez stocker la session dans le httpcontext et ça ira probablement bien.

+0

J'ai déplacé les sessions et les discussions dans HttpContext.Current.Items et le même comportement se produit exactement. – mikeschuld

+0

Pouvez-vous montrer plus de code afin de reproduire l'erreur? – Paco

+0

Une combinaison du déplacement vers HttpContext AND la fermeture et l'élimination manuelle des connexions semble avoir résolu ce problème. J'ai ajouté un bloc pour démarrer une transaction s'il y a une erreur "Non démarré" et il semble capturer toutes les opérations qui doivent se produire dans ce contexte ainsi tout semble bien maintenant. – mikeschuld

Questions connexes