2

transaction.Rollback()以下是我的代码的代表性片段,其中在语句中抛出了一个意外的(至少就我而言)异常。

异常是类型NHibernate.TransactionException,消息是“事务未连接,或已断开连接”。堆栈跟踪如下所示NHibernate.Transaction.AdoTransaction.CheckNotZombied() at NHibernate.Transaction.AdoTransaction.Rollback()

IEmployeeService employeeService = new EmployeeService(session);
var people = ReadFromFile('c:\temp.csv');

for (var person in people)
{
    ITransaction transaction = session.BeginTransaction();
    try
    {
        employeeService.Update(person);

        employeeService.CheckForRecursion();

        transaction.Commit();
    }
    catch(Exception exp)
    {
        if (!transaction.WasRolledBack)
            transaction.Rollback();
    }
}

CheckForRecursion 使用一些 SQL 来查找上次更新引入的任何递归,如果是这样我想撤消。当引入递归时,SQL 会冒出一个异常,这是正确的,我抓住它并尝试回滚。那是我遇到错误的时候。

我已将回滚包装在 try catch 中,因此整个事情可以继续进行,但我在 for 循环的每次后续迭代中都看到相同的异常。

想法?这个模式正确吗?

4

2 回答 2

2

当表上的触发器引发错误时,我收到此错误。我修复了触发器,交易错误消失了。

我在输出窗口中显示了 NHibernate 生成的 SQL,因此我采用了最后生成的 sql 语句并在查询工具中运行它。触发器引发了关于截断字符串值的错误。

这是一个带有触发器的表的示例,它将在 NHibernate 中导致这种错误。

CREATE TABLE myTable (
    id int IDENTITY(1,1) NOT NULL,
    ThisIsA10CharField varchar(10),
    CONSTRAINT myTable_pk PRIMARY KEY CLUSTERED (id));
GO

CREATE TRIGGER myTable_MakeError ON myTable AFTER INSERT AS 
BEGIN
    INSERT INTO myTable (ThisIsA10CharField) values ('this will raise a truncate error')
END
GO

INSERT INTO mytable (ThisIsA10CharField) values ('x')

消息 8152,级别 16,状态 14,过程 myTable_MakeError,第 4 行字符串或二进制数据将被截断。该语句已终止。

于 2016-01-05T20:26:24.493 回答
1

你为什么不直接处理交易?

using (ITransaction transaction = session.BeginTransaction())
{
    employeeService.Update(person);

    employeeService.CheckForRecursion();

    transaction.Commit();
}

当发生异常时,您应该销毁会话。更改已在此人身上进行,但并未撤消。不能存储时,在内存中无效。

于 2013-01-15T16:41:42.417 回答