简要地:
- 始终使用事务
- 不要使用
Close()
,而是将调用包装在语句ISession
内部或在其他地方管理 ISession 的生命周期。using
从文档中:
将不时ISession
执行将 ADO.NET 连接状态与内存中保存的对象状态同步所需的 SQL 语句。这个过程,flush,默认发生在以下几点
- 从某些调用
Find()
或Enumerable()
- 从
NHibernate.ITransaction.Commit()
- 从
ISession.Flush()
SQL 语句按以下顺序发出
- 所有实体插入,以相同的顺序保存相应的对象
ISession.Save()
- 所有实体更新
- 所有集合删除
- 所有集合元素的删除、更新和插入
- 所有集合插入
- 所有实体删除,以相同的顺序删除相应的对象,使用
ISession.Delete()
(一个例外是使用原生 ID 生成的对象在保存时被插入。)
除非您明确表示Flush()
,否则绝对不能保证 Session 何时执行 ADO.NET 调用,只能保证它们的执行顺序。然而,NHibernate 确实保证这些ISession.Find(..)
方法永远不会返回过时的数据。他们也不会返回错误的数据。
可以更改默认行为以减少刷新频率。该类FlushMode
定义了三种不同的模式:仅在提交时刷新(并且仅在使用 NHibernate ITransaction
API 时),使用解释的例程自动刷新,或从不刷新,除非Flush()
显式调用。最后一种模式对于长时间运行的工作单元很有用,其中 anISession
长时间保持打开和断开连接。
...
另请参阅本节:
结束会话涉及四个不同的阶段:
刷新会话
如果您恰好使用ITransaction
API,则无需担心此步骤。它会在事务提交时隐式执行。否则,您应该调用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()
将其返回到池中。