【发布时间】:2010-10-15 10:24:22
【问题描述】:
我在使用 NHIbernate 时遇到了一个奇怪的问题,鉴于这是我的第一个 NHIbernate 项目,我想我会问 StackOverflow.com 的好人。
我在 ASP.Net 中遵循“在视图中打开会话”模式,它在每个请求上打开一个休眠事务并在请求结束时提交它。
这正常工作,但是在我的一个页面上,这只是一个读取页面而不是写入页面,我遇到了一个问题。相关页面获取项目列表,并根据它们对信息进行一些查询。
作为其中的一部分,它调用一个外部 DLL,该 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 这样做: - 在 HTTPContext 中存储一个 ITransaction + ISession。这些可以作为名为 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;
}
}
【问题讨论】:
-
您能提供更多信息吗? sn-ps 的代码,可能有用。
-
添加了代码。我刚刚还发现,在调用 DLL 之前提交事务,然后在工作后开始一个新事务。但问题是,为什么 dll 只是做一个简单的 ado.net executeReader,到底为什么会被阻止?
标签: c# .net nhibernate transactions