Nhibernate事务已成功提交,但查询的结果仍然是未修改的值



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

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;
}
}

然后执行下面的查询(查询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);

因此,我修改了第一段代码,并明确地调用了update方法(请参阅注释中的代码(,这次一切都很好。

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

希望有人能帮我解释一下这是怎么回事。

您首先执行查询session.Get<Task>(taskId);。这将在一级缓存中加载实体。

然后在您的交易中,您Get就是Promotion实体。Task是它的IEnumerable属性。由于可能是延迟加载,您的foreach循环迭代通过ID为taskIDTask实体-修改它-更新它-事务成功。由于所有这些都发生在事务内部,session.Get<Task>(taskId);返回的初始实体不会更新。它仍然持有旧的价值观。

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

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

了解你的ISession是你的工作单元;仔细观察。

相关内容

  • 没有找到相关文章

最新更新