使用Session.Flush然后ITransaction.Commit进行数据回滚

时间:2012-12-24 15:42:02

标签: sql-server nhibernate

我正在尝试使用Session.Update更新实体,然后继续执行另一个SQL查询。另一个查询没有看到更改的值。当我使用分析器跟踪它时,Session.Update什么也没做。

public class InvoiceService()
{
    public void Update(Invoice invoice)
    {
        using (var trans = BeginTransaction())
        {
            Session.Update(invoice); //Nhibernate did not update invoice. 

            ExecuteNamedQuery(); //Query executed before invoice updated.

            trans.Commit(); //Invoice updated.
        }
    }
}

然后我在Session.Update之后添加Session.Flush。

using (var trans = BeginTransaction())
{
    Session.Update(invoice);
    Session.Flush()

    ExecuteNamedQuery();

    trans.Commit();
}

执行Session.Flush后,还会执行SQL查询以进行更新。 它完美地运作。执行顺序是正确的。但后来我执行了另一种方法来获取所有发票。提交事务使nhibernate执行更新查询以更早地使用旧值更新我更新的发票。 (例如:数量= 20,更新为10,然后再次更新为20)

public void FindAll()
{
    using (var trans = BeginTransaction())
    {
        var invoices = Session.CreateCriteria<Invoice>().List<Invoice>();

        trans.Commit(); // In here invoice that i updated earlier get updated again, using old values.

        return invoices;
    }
}

为什么会再次更新?

这个问题的解决方案是什么?

提前致谢。

1 个答案:

答案 0 :(得分:3)

Update是该方法的一个不幸名称; Update的目的是将临时实例附加到新会话。请参阅documentation for update并确保您了解instance states

发票更新为原始值,因为NHibernate认为它已更改。此“幻像”更新可能是由于属性意外更改引起的。典型的根本原因是映射到非可空属性的可空数据库列(反之亦然)。最简单的故障排除方法是在会话工厂配置中打开dynamic-update,以便您可以看到NHibernate检测到哪些属性为脏。