小编典典

NHibernate ISession Flush:何时何地使用它,为什么?

all

让我彻底困惑的一件事是, 与和session.Flush结合使用。session.Commit``session.Close

有时session.Close有效,例如,它提交了我需要的所有更改。我知道当我有一个事务或一个具有多个创建/更新/删除的工作单元时我需要使用提交,以便在发生错误时我可以选择回滚。

但有时我真的被背后的逻辑所阻碍session.Flush。我见过一些例子,你有一个session.SaveOrUpdate()后跟冲洗,但是当我删除冲洗它无论如何都可以正常工作。有时我在
Flush 语句中遇到错误,说会话超时,删除它确保我没有遇到该错误。

有没有人对何时何地使用 Flush 有很好的指导?我已经为此检查了 NHibernate 文档,但我仍然找不到一个简单的答案。


阅读 94

收藏
2022-07-28

共1个答案

小编典典

简要地:

  1. 始终使用事务
  2. 不要使用Close(),而是将调用包装在语句ISession内部或 在其他地方管理 ISession 的生命周期*using *

文档中

将不时ISession执行将 ADO.NET 连接状态与内存中保存的对象状态同步所需的 SQL 语句。这个过程,flush,默认发生在以下几点

  • 从某些调用Find()Enumerable()
  • NHibernate.ITransaction.Commit()
  • ISession.Flush()

SQL 语句按以下顺序发出

  1. 所有实体插入,以相同的顺序保存相应的对象ISession.Save()
  2. 所有实体更新
  3. 所有集合删除
  4. 所有集合元素的删除、更新和插入
  5. 所有集合插入
  6. 所有实体删除,以相同的顺序删除相应的对象,使用ISession.Delete()

(一个例外是使用原生 ID 生成的对象在保存时被插入。)

除非您明确表示Flush(),否则绝对不能保证 Session 何时执行 ADO.NET
调用,只能保证它们的执行顺序
。然而,NHibernate
确实保证这些ISession.Find(..)方法永远不会返回过时的数据。他们也不会返回错误的数据。

可以更改默认行为以减少刷新频率。该类FlushMode定义了三种不同的模式:仅在提交时刷新(并且仅在使用 NHibernate
ITransactionAPI
时),使用解释的例程自动刷新,或从不刷新,除非Flush()显式调用。最后一种模式对于长时间运行的工作单元很有用,其中
anISession长时间保持打开和断开连接。

另请参阅本节

结束会话涉及四个不同的阶段:

  • 刷新会话
  • 提交事务
  • 关闭会话
  • 处理异常

刷新会话

如果您恰好使用ITransactionAPI,则无需担心此步骤。它会在事务提交时隐式执行。否则,您应该调用ISession.Flush()以确保所有更改都与数据库同步。

提交数据库事务

如果您使用的是 NHibernate ITransaction API,则如下所示:

tx.Commit(); // flush the session and commit the transaction

如果您自己管理 ADO.NET 事务,则应手动管理 ADO.NETCommit()事务。

sess.Flush();
currentTransaction.Commit();

如果您决定不提交更改:

tx.Rollback();  // rollback the transaction

或者:

currentTransaction.Rollback();

如果您回滚事务,您应该立即关闭并丢弃当前会话,以确保 NHibernate 的内部状态是一致的。

关闭 ISession

调用ISession.Close()标记会话的结束。Close() 的主要含义是会话将放弃 ADO.NET 连接。

tx.Commit();
sess.Close();

sess.Flush();
currentTransaction.Commit();
sess.Close();

如果您提供了自己的连接,Close()则返回对其的引用,因此您可以手动关闭它或将其返回到池中。否则Close()将其返回到池中。

2022-07-28