У меня странная проблема с NHIbernate, и, учитывая, что это мой первый проект NHIbernate, я решил спросить хороших людей из StackOverflow.com.
Я следую шаблону «Открыть сеанс в представлении» в ASP.Net, который открывает транзакцию гибернации при каждом запросе и фиксирует ее в конце запроса.
Это нормально работает, однако на одной из моих страниц, которая является просто страницей для чтения, а не страницей для записи, возникает проблема. Страница, о которой идет речь, получает список проектов и выполняет несколько запросов информации на их основе.
Как часть этого, он вызывает внешнюю DLL, в которой есть SQL-запрос к базе данных. Этот вызов работает для всех проектов, кроме одного, где он получает тайм-аут на вызов ExecuteReader ().
После некоторой попытки найти ошибку во внешнем DLl я решил закомментировать установление транзакции внутри обработчика http. Это устранило проблему.
Итак, каким-то образом управление сеансом гибернации влияет на внешнюю, не связанную (ну, есть вероятность, что некоторые сопоставления касаются тех же баз данных, которые используются в этом запросе, однако его чтение доступно только на обоих концах)
Мой вопрос: почему он это делает? Что делает nhibernate под капотом, что приводит к превышению времени ожидания других SQL-запросов? Я полагаю, что он блокирует какую-то часть базы данных, но почему он это делает, если страница только читает? Как я могу обойти это?
редактирование:
следующие части этого руководства
http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
Дополнительная информация:
У меня есть IHttpModule, который делает следующее в BeginRequest
private void BeginTransaction(object sender, EventArgs e)
{
Console.WriteLine("Begin Transaction");
NHibernateSessionManager.Instance.BeginTransaction();
}
затем при закрытии
private void CommitAndCloseSession(object sender, EventArgs e)
{
Console.WriteLine("End Transaction");
try
{
NHibernateSessionManager.Instance.CommitTransaction();
}
finally
{
NHibernateSessionManager.Instance.CloseSession();
}
}
NHIbernateSEssionManager делает это:
- сохраняет ITransaction + ISession в HTTPContext. Они доступны как объекты с именами ContextTransaction и ContextSession. Они используются в:
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;
}
}