NHibernate - 回滚事务和关闭会话会导致抛出GenericADOException

时间:2013-02-08 19:30:29

标签: c# nhibernate transactions

我在这里做错了。我不明白为什么NHibernate试图在这种情况下提交任何东西。

我提供了一个“描述”字段,其长度大于200个字符。我有一个叫做的验证器:

Order.ValidateAndThrow(Order);
RuleFor(order => order.Description).Length(0, 200).WithName("Description");

因为我的描述长度大于200个字符 - ValidateAndThrow会抛出异常。

这是处理异常的catch块:

catch (Exception exception)
{
    Logger.Error(exception);
    NHibernateSessionManager.Instance.RollbackTransaction();
    throw;
}

public void RollbackTransaction()
{
    ITransaction transaction = ContextTransaction;

    try
    {
        if (HasOpenTransaction())
        {
            transaction.Rollback();
        }

        ContextTransaction = null;
    }
    finally
    {
        CloseSession();
    }
}

/// <summary>
/// Flushes anything left in the session and closes the connection.
/// </summary>
public void CloseSession()
{
    ISession session = ContextSession;

    if (session != null && session.IsOpen)
    {
        session.Flush();
        session.Close();
    }

    ContextSession = null;
}

所以,我看到发生的事情是transaction.Rollback()语句成功执行,然后调用CloseSession()。

在CloseSession()内部,执行session.Flush()。这导致我的Order实体显然尝试并保存到数据库中。我以为我刚刚回滚了我的改变?

然而,调用SessionClose()会生成GenericADOException。内部异常消息显示为"{"String or binary data would be truncated.\r\nThe statement has been terminated."}"

在这种情况下,我该如何正确退出交易?

1 个答案:

答案 0 :(得分:1)

根据文件here

  

如果您正在使用ITransaction API,则无需担心此步骤[刷新会话]。它将在提交事务时隐式执行。

因此,如果您使用的是NHibernate&#39; ITransaction.Commit(),则无需刷新。如果交易被回滚,你肯定不想要冲洗。只要确保你总是关闭会话。