【发布时间】:2013-02-04 14:01:43
【问题描述】:
我确定这是有效的,现在已经停止,我不知道为什么。我的课程太复杂,无法发布,但我做了一个简单的课程进行测试,它仍在进行中。
我创建了一个类“abc”,它有几个在数据库中不为空的属性。我创建了该类的一个实例,并故意将属性保留为 null,以便它会引发错误。在输出窗口中,错误显示为
“System.Data.SqlClient.SqlException”类型的第一次机会异常 发生在 System.Data.dll 类型的第一次机会异常 'NHibernate.Exceptions.GenericADOException' 发生在 NHibernate.DLL 中
但是异常并没有冒泡到我的代码并且没有问题地运行。该行不在数据库中,如果我从 SQL 探查器复制 SQL,我会得到正确的错误“无法将 null 插入列......”
问题是我在事务中创建了几个对象,如果一个对象失败,我希望抛出一个错误,以便我可以回滚所有对象,但由于错误没有冒泡,我无法捕获它们,所以我无法回滚。
以下实际上不是代码,而是为了说明我的意思:
using (NHibernate.ITransaction tx = Session.BeginTransaction())
{
try
{
// Should Fail
ABC a1 = new ABC();
a1.prop1 = "1234";
Session.SaveOrUpdate(a1);
// Should Save
ABC a2 = new ABC();
a2.prop1 = "1234";
a2.prop2 = "1234";
Session.SaveOrUpdate(a2);
// Should Fail
ABC a3 = new ABC();
Session.SaveOrUpdate(a3);
tx.Commit()
}
catch (Exception ex)
{
tx.Rollback()
throw ex;
}
}
在上述对象中,a1 和 a3 应该在插入失败时抛出错误(并在输出窗口中看到),但它不会被 catch {} 语句捕获,它只是逐步执行所以tx.commit 运行并且a2 被持久化到数据库中(shouldn't 发生)。
有什么想法吗? 泰。
【问题讨论】:
-
与问题无关...但您应该只使用
throw,而不是throw ex。我认为它保留了原始堆栈跟踪。 -
是的,上面不是实际代码,是我的想法。我记录错误,然后将其传递给处理程序,而不是重新抛出。关键是它甚至没有到达那里,它应该到达那里。
-
你如何处理 NHibernateSession?休眠版本?
-
您有任何客户 NHibernate 事件侦听器、拦截器或类似的东西吗?
-
正如@OskarBerggren 所指出的,我将首先查看自定义处理程序,然后确保对 Session 的每次调用都不会实例化新的 Session,然后,如果将所有 SaveOrUpdate 替换为 Save 是否会有所不同,然后在每次 Save/SaveOrUpdate 后尝试刷新
标签: c# sql-server nhibernate