【问题标题】:The Nhibernate transaction has been successfully committed, but the result of the query is still the unmodified valueNhibernate事务已经提交成功,但是查询的结果还是未修改的值
【发布时间】:2020-07-04 22:55:49
【问题描述】:

执行以下服务器代码,然后检查数据库中的促销表和任务表。相关字段已正确更新,说明事务已成功提交。

using (ITransaction tx = session.BeginTransaction())
{
    try
    {
        Promotion p = session.Get<Promotion>(request.PromotionId);
        p.Status = PromotionStatus.Canceled;
        foreach (Task task in p.Tasks)
        {
            if (task.AnnounceStatus == TaskAnnounceStatus.New)
            {
                task.AnnounceStatus = TaskAnnounceStatus.PromotionCanceled;
                task.CancelTime = DateTime.Now;
                //session.Update(task);
            }
        }
        tx.Commit();
    }   
    catch
    {
        tx.Rollback();
        throw;
    }
}

然后执行下面的查询(Query A),得到的数据也是更新后的值。看起来一切都很好。

tasks = session.Query<Task>().Where(p => p.AnnounceStatus == Model.TaskAnnounceStatus.New && p.ProcessStatus == Model.TaskProcessStatus.New).ToList();

但是,如果我在提交事务之前使用以下代码对任务执行查询,则上述查询的结果(查询 A)将获得旧的未修改值。同时,您在数据库中看到的仍然是正确更新的值。

Task task = session.Get<Task>(taskId);

所以我修改了第一段代码,并显式调用了更新方法(见注释处的代码),这次一切正常。

我的猜测是 Nhibernate 的缓存导致了上述问题。我使用syscache2管理二级缓存,缓存设置为ReadWrite,使用sessionFacotry.getCurrentSession管理Nhibernate的会话。

希望有人能帮我解释一下这是如何工作的。

【问题讨论】:

  • 以上三段代码位于session的独立作用域,每次都通过NHibernateHelper.GetCurrentSession()获取session。所以我认为问题出在二级缓存上。如果没有显式调用update方法,我认为nhibernate不会在事务提交的时候同步更新二级缓存。

标签: nhibernate transactions second-level-cache


【解决方案1】:

您首先执行查询session.Get&lt;Task&gt;(taskId);。这会将实体加载到一级缓存中。

然后在您的交易中,您 GetPromotion 实体。 Task 是它的 IEnumerable 属性。由于可能是延迟加载,您的 foreach 循环遍历 ID 为 taskIDTask 实体 - 修改它 - 更新它 - 交易成功。由于所有这些都发生在事务中,session.Get&lt;Task&gt;(taskId); 返回的初始实体不会更新。它仍然保持旧值。

然后,你在事务之外再次session.Query&lt;Task&gt;()。这一次,NHibernate 看到具有相同标识符的实体已经加载到会话缓存中(使用session.Get&lt;Task&gt;(taskId); 查询),它不会再次加载该实体,它只是返回已经在会话缓存中的实体。由于该实体持有旧值,您就会发现问题所在。

要确认这一点,请将所有这些查询放入事务块中并检查结果。
或者,正确管理session 的范围。

明白你的ISession就是你的Unit Of Work;仔细确定范围。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-23
    • 2016-07-08
    相关资源
    最近更新 更多