为什么 NHibernate IPreUpdateEventListener/IPreInsertEventListener 中没有活动事务?
我正在使用 NHibernate 3。我的应用程序在 SQL Server 2008 上运行时工作正常,但在 SQL 2000 上会出现间歇性错误(我们已适当更改了 NH 方言)。这些错误都与MDTC(分布式事务)组件有关。通常读取工作正常,但代码在保存/更新期间崩溃,但并不总是出现相同的错误。我们经常看到的是,“分布式事务已完成”。在新事务或 NULL 事务中登记此会话。
我正在调查其根本原因并添加了一些日志记录。我定义了 IPreUpdateEventListener 和 IPreInsertEventListener 拦截器,因此我登录到那里以及我的存储库中。我发现,当我到达侦听器时,当前会话中没有事务。
这是我的存储库代码:
public virtual void Save(object entity)
{
logger.DebugFormat("Opening transaction to save entity type {0}.", entity.GetType().Name);
using (var t = new TransactionScope())
{
GetSession().SaveOrUpdate(entity);
logger.DebugFormat("Committing transaction.");
t.Complete();
}
}
这是我的事件侦听器代码:
logger.DebugFormat("Save/Insert entity. Transaction.Active = {0}",
persister.Factory.GetCurrentSession().Transaction != null
? persister.Factory.GetCurrentSession().Transaction.IsActive.ToString()
: "no transaction");
这是日志输出:
2011-01-14 17:23:13,549 [9] DEBUG BaseRepository`1.Save - Opening transaction to save entity type XXXXXXX.
2011-01-14 17:23:13,566 [9] DEBUG BaseRepository`1.Save - Committing transaction.
2011-01-14 17:23:13,598 [9] DEBUG AuditEventListener.Audit - Save/Insert entity. Transaction.Active = False
你能看出这有什么问题吗?为什么预插入时没有交易活跃?有谁知道我需要为 Sql Server 2000 做些什么特别的事情(MSDTC 已打开)?
注意,2008环境是我运行Windows 7的本地机器,Sql Server 2000服务器是Server 2003。
I am using NHibernate 3. My application works fine when run against SQL Server 2008 but has intermittent errors on SQL 2000 (we've changed the NH dialect appropriately). The errors are all related to the MDTC (distributed transaction) component. Typically reads work okay but the code blows up during save/update but not always with the same error. One we've seen often is, 'Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.'.
I am investigating the root causes of this and have added some logging. I have IPreUpdateEventListener and IPreInsertEventListener interceptors defined so I log in there as well as in my repository. What I am finding is that by the time I get to my listener, there is no transaction on the current session.
Here is my repository code:
public virtual void Save(object entity)
{
logger.DebugFormat("Opening transaction to save entity type {0}.", entity.GetType().Name);
using (var t = new TransactionScope())
{
GetSession().SaveOrUpdate(entity);
logger.DebugFormat("Committing transaction.");
t.Complete();
}
}
And here is my event listener code:
logger.DebugFormat("Save/Insert entity. Transaction.Active = {0}",
persister.Factory.GetCurrentSession().Transaction != null
? persister.Factory.GetCurrentSession().Transaction.IsActive.ToString()
: "no transaction");
And here is the log output:
2011-01-14 17:23:13,549 [9] DEBUG BaseRepository`1.Save - Opening transaction to save entity type XXXXXXX.
2011-01-14 17:23:13,566 [9] DEBUG BaseRepository`1.Save - Committing transaction.
2011-01-14 17:23:13,598 [9] DEBUG AuditEventListener.Audit - Save/Insert entity. Transaction.Active = False
Can you see anything wrong with this? Why is there no transaction active in pre-insert? Does anyone know of anything special I need to do for Sql Server 2000 (MSDTC is switched on)?
Note that the 2008 environment is my local machine running Windows 7 and the Sql Server 2000 server is Server 2003.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
TransactionScope不创建 NHibernate 事务。
您必须使用
session.BeginTransaction()
显式创建它。它将自动加入分布式事务(不要忘记在 Complete 之前Commit()
)TransactionScope does not create a NHibernate transaction.
You have to create it explicitly, using
session.BeginTransaction()
. It will be automatically enlisted in the distributed transaction (don't forget toCommit()
it before Complete)