NHibernate Flush--它是如何工作的?

时间:2009-04-23 08:09:21

标签: nhibernate

我对NHibernate中Flush(和NHibernate.ISession)的工作原理感到困惑。

从我的代码中可以看出,当我使用ISession.Save(entity)保存对象时,该对象可以直接保存到数据库中。

但是,当我使用ISession.SaveOrUpdate(entity)ISession.Update(entity)更新和对象时,数据库中的对象未更新 - 我需要调用ISession.Flush才能更新它。 / p>

关于如何更新对象的过程如下:

  1. 使用ISession.Get(typeof(T), id)
  2. 从数据库中获取对象
  3. 更改对象属性,例如myCar.Color="Green"
  4. 使用ISession.Update(myCar)
  5. 将其提交回数据库

    myCar未更新为数据库。但是,如果我之后调用ISession.Flush,则会更新。

    何时使用Flush,何时不使用?

2 个答案:

答案 0 :(得分:28)

在很多情况下,当NHibernate刷新时你不必关心。

您只需要在创建自己的连接时调用flush ,因为NHibernate不知道您何时提交它。

对您来说真正重要的是交易。在事务期间,您与其他事务隔离,这意味着,当您从数据库中读取数据时,总是会看到您的更改,并且您没有看到其他事务更改(除非它们已提交)。因此,除非提交数据,否则NHibernate更新数据库中的数据时您不必关心。无论如何,任何人都看不到它。

如果

,NHibernate会刷新
  • 你召集提交
  • 在查询之前确保按内存中的实际状态进行过滤
  • 当你打电话时冲洗

示例:

using (session = factory.CreateSession())
using (session.BeginTransaction())
{
  var entity = session.Get<Entity>(2);
  entity.Name = "new name";

  // there is no update. NHibernate flushes the changes.

  session.Transaction.Commit();
  session.Close();
}

实体在提交时更新。 NHibernate看到您的会话是脏的并刷新对数据库的更改。只有在会话之外进行了更改时,才需要更新和保存。 (这意味着使用分离的实体,即会话不知道的实体)。


性能说明: Flush不仅执行必需的SQL语句来更新数据库。它还会搜索内存中的更改。由于POCO上没有脏标志,因此需要将会话中每个对象的每个属性与其第一级缓存进行比较。如果经常这样做,这可能会成为性能问题。您可以采取一些措施来避免性能问题:

  • 不要在循环中冲洗
  • 避免使用序列化对象(需要序列化来检查更改)
  • 在适当的时候使用read-only entities
  • 在适当的时候设置mutable = false
  • 在属性中使用自定义类型时,请实现有效的Equals方法
  • 当您确定知道自己在做什么时,请小心禁用自动冲洗。

答案 1 :(得分:6)

NHibernate只在必要时执行SQL语句。它将尽可能推迟SQL语句的执行。

例如,当您保存具有指定ID的实体时,它可能会推迟INSERT语句的执行。 但是,当您插入一个具有自动增量id的实体时,NHibernate需要直接插入实体,因为它必须知道将分配给该实体的ID。

当您显式调用flush时,NHibernate将执行在该会话中已更改/创建/删除的对象所必需的SQL语句。

Flush