2010-10-15 7 views
0

J'ai un problème étrange avec NHIbernate, et voyant que c'est mon premier projet NHIbernate je pensais que je demanderais aux bonnes personnes de StackOverflow.com. Je suis le modèle 'Ouvrir une session dans la vue' dans ASP.Net, qui ouvre une transaction d'hibernation sur chaque requête et la valide à la fin de la requête.NHIbernate affectant les requêtes non-nhibernate?

Cela fonctionne normalement, mais sur l'une de mes pages, qui est simplement une page de lecture et non une écriture, j'ai un problème. La page en question obtient une liste de projets, et fait quelques requêtes d'informations basées sur eux. Dans le cadre de cela, il appelle une DLL externe, qui a une requête SQL à une base de données à l'intérieur de celui-ci. Cet appel semble fonctionner pour tous les projets à l'exception d'un, où il obtient un délai d'expiration sur l'appel ExecuteReader(). Après avoir essayé de trouver un bug dans le DLl externe pendant un certain temps, je décide de commenter l'établissement de la transaction à l'intérieur du gestionnaire http. Cela corrige le problème.

Ainsi, et hiberne en quelque sorte la gestion de la session touche externe, sans rapport (bien, il y a une chance que certaines des applications touchent les mêmes bases de données utilisées dans cette requête, mais sa lecture seule sur les deux extrémités)

Ma question est: pourquoi fait-elle cela? Que fait nhibernate sous le capot qui provoque l'expiration du délai des autres requêtes SQL? Je suppose qu'il a un verrou sur une partie de la base de données, mais pourquoi fait-il cela si la page ne lit que? Comment puis-je contourner cela?

modifier: parties suivantes de ce guide http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

Plus d'info: J'ai un IHttpModule qui fait ce qui suit dans BeginRequest

private void BeginTransaction(object sender, EventArgs e) 
    { 
     Console.WriteLine("Begin Transaction"); 
     NHibernateSessionManager.Instance.BeginTransaction(); 
    } 

puis sur Fermer

private void CommitAndCloseSession(object sender, EventArgs e) 
    { 
    Console.WriteLine("End Transaction"); 
    try 
    { 

     NHibernateSessionManager.Instance.CommitTransaction(); 
    } 
    finally 
    { 
     NHibernateSessionManager.Instance.CloseSession(); 
    } 
} 

Le NHIbernateSEssionManager fait ceci: - stocke un ITransaction + ISession dans le HTTPContext. Ceux-ci sont accessibles en tant que propriétés nommées ContextTransaction et ContextSession. Ils sont utilisés dans:

public void BeginTransaction() 
     { 
      ITransaction transaction = ContextTransaction; 

      if (transaction == null) 
      { 
       transaction = GetSession().BeginTransaction(); 
       ContextTransaction = transaction; 
      } 
     } 

    public void CommitTransaction() 
     { 
      ITransaction transaction = ContextTransaction; 

      try 
      { 
       if (HasOpenTransaction()) 
       { 
        transaction.Commit(); 
        ContextTransaction = null; 
       } 
      } 
      catch (HibernateException) 
      { 
       RollbackTransaction(); 
       throw; 
      } 
     } 
+0

pourriez-vous mettre plus d'informations? Des extraits de code peuvent être utiles. –

+0

Code ajouté. Je viens aussi de découvrir que valider la transaction avant d'appeler la DLL puis en commencer une nouvelle après les travaux. Mais la question est, pourquoi, la DLL fait juste un simple ado.net executeReader, pourquoi diable est-ce être bloqué? – RodH257

Répondre

0

Je suppose qu'il y a une transaction distribuée ambiante qui cause les impacts croisés. Utilisez-vous la classe TransactionScope pour gérer les transactions?

+0

Lire la documentation. – TomTom

+0

TomTom, ce n'est pas utile, merci. @Lucero merci pour votre réponse, je n'utilise pas explicitement TransactionScope (j'ai mis à jour le message principal avec du code), NHibernate n'a-t-il pas intégré le support des transactions? Ou dites-vous que je devrais utiliser transactionscope dans la DLL séparée? – RodH257

Questions connexes