I have got an odd problem with NHIbernate, and seeing as this is my first NHIbernate project I thought I'd ask the good people of StackOverflow.com.
I'm following the 'Open session in view' pattern in ASP.Net, which opens a hibernate transaction on each request and commits it at the end of the request.
This works fine normally, however on one of my pages, which is simply a read page not a write one, I get an issue. The page in question gets a list of projects, and does a few queries for information based on them.
As a part of that, it calls an external DLL, which has an SQL Query to a database inside of it. This call appears to work for all projects except for one, where it gets a timeout on the ExecuteReader() call.
After trying to find a bug in the external DLl for some time, I decide to comment out the establishing of the transaction inside of the http handler.This fixed the issue.
So, somehow hibernates session management is affecting external, unrelated (well, there is a chance that some of the mappings touch the same databases that are used in that query, however its read only on both ends)
My question is, why is it doing this? What is nhibernate doing under the hood that causes other SQL queries to timeout? I take it it has a lock on some part of the database, but why is it doing that if the page only reads? How can I get around this?
edit: following parts of this guide http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
More info: I have a IHttpModule that does the following in BeginRequest
private void BeginTransaction(object sender, EventArgs e)
{
Console.WriteLine("Begin Transaction");
NHibernateSessionManager.Instance.BeginTransaction();
}
then on close
private void CommitAndCloseSession(object sender, EventArgs e)
{
Console.WriteLine("End Transaction");
try
{
NHibernateSessionManager.Instance.CommitTransaction();
}
finally
{
NHibernateSessionManager.Instance.CloseSession();
}
}
The NHIbernateSEssionManager does this: - stores an ITransaction + ISession in the HTTPContext. These are accessible as proprties named ContextTransaction and ContextSession. These are used in:
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;
}
}