NHibernate ISession Flush:何时何地使用它,为什么? [英] NHibernate ISession Flush: Where and when to use it, and why?

查看:26
本文介绍了NHibernate ISession Flush:何时何地使用它,为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我彻底困惑的一件事是使用 session.Flush,结合 session.Commitsession.Close.

One of the things that get me thoroughly confused is the use of session.Flush,in conjunction with session.Commit, and session.Close.

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

Sometimes session.Close works, e.g., it commits all the changes that I need. I know I need to use commit when I have a transaction, or a unit of work with several creates/updates/deletes, so that I can choose to rollback if an error occurs.

但有时我真的被 session.Flush 背后的逻辑所困扰.我看过一些例子,你有一个 session.SaveOrUpdate() 后跟一个刷新,但是当我删除 Flush 时它仍然可以正常工作.有时我会在 Flush 语句中遇到错误,说会话超时,删除它可以确保我没有遇到那个错误.

But sometimes I really get stymied by the logic behind session.Flush. I have seen examples where you have a session.SaveOrUpdate() followed by a flush, but when I remove Flush it works fine anyway. Sometimes I run into errors on the Flush statement saying that the session timed out, and removing it made sure that I didn't run into that error.

有没有人有关于在何处或何时使用 Flush 的良好指南?我已经为此查看了 NHibernate 文档,但我仍然找不到直接的答案.

Does anyone have a good guideline as to where or when to use a Flush? I've checked out the NHibernate documentation for this, but I still can't find a straightforward answer.

推荐答案

简要说明:

  1. 始终使用事务
  2. 不要使用Close(),而是将您的调用包装在ISession 内的using 语句中或管理生命周期其他地方的 ISession .
  1. Always use transactions
  2. Don't use Close(), instead wrap your calls on an ISession inside a using statement or manage the lifecycle of your ISession somewhere else.

来自文档:

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

From time to time the ISession will execute the SQL statements needed to synchronize the ADO.NET connection's state with the state of objects held in memory. This process, flush, occurs by default at the following points

  • 来自 Find()Enumerable() 的一些调用
  • 来自 NHibernate.ITransaction.Commit()
  • 来自 ISession.Flush()
  • from some invocations of Find() or Enumerable()
  • from NHibernate.ITransaction.Commit()
  • from ISession.Flush()

SQL 语句按以下顺序发出

The SQL statements are issued in the following order

  1. 所有实体插入,以相同的顺序使用ISession.Save()
  2. 保存相应的对象
  3. 所有实体更新
  4. 所有集合删除
  5. 所有集合元素的删除、更新和插入
  6. 所有集合插入
  7. 所有实体删除,使用ISession.Delete()
  8. 以相同的顺序删除相应的对象
  1. all entity insertions, in the same order the corresponding objects were saved using ISession.Save()
  2. all entity updates
  3. all collection deletions
  4. all collection element deletions, updates and insertions
  5. all collection insertions
  6. all entity deletions, in the same order the corresponding objects were deleted using ISession.Delete()

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

(An exception is that objects using native ID generation are inserted when they are saved.)

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

Except when you explicity Flush(), there are absolutely no guarantees about when the Session executes the ADO.NET calls, only the order in which they are executed. However, NHibernate does guarantee that the ISession.Find(..) methods will never return stale data; nor will they return the wrong data.

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

It is possible to change the default behavior so that flush occurs less frequently. The FlushMode class defines three different modes: only flush at commit time (and only when the NHibernate ITransaction API is used), flush automatically using the explained routine, or never flush unless Flush() is called explicitly. The last mode is useful for long running units of work, where an ISession is kept open and disconnected for a long time.

...

另请参阅本部分:

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

Ending a session involves four distinct phases:

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

如果您碰巧使用了 ITransaction API,则无需担心这一步.它将在事务提交时隐式执行.否则,您应该调用 ISession.Flush() 以确保所有更改都与数据库同步.

If you happen to be using the ITransaction API, you don't need to worry about this step. It will be performed implicitly when the transaction is committed. Otherwise you should call ISession.Flush() to ensure that all changes are synchronized with the database.

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

If you are using the NHibernate ITransaction API, this looks like:

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

如果您自己管理 ADO.NET 事务,您应该手动Commit() ADO.NET 事务.

If you are managing ADO.NET transactions yourself you should manually Commit() the ADO.NET transaction.

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

如果您决定不提交更改:

If you decide not to commit your changes:

tx.Rollback();  // rollback the transaction

或:

currentTransaction.Rollback();

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

If you rollback the transaction you should immediately close and discard the current session to ensure that NHibernate's internal state is consistent.

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

A call to ISession.Close() marks the end of a session. The main implication of Close() is that the ADO.NET connection will be relinquished by the session.

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

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

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

If you provided your own connection, Close() returns a reference to it, so you can manually close it or return it to the pool. Otherwise Close() returns it to the pool.

这篇关于NHibernate ISession Flush:何时何地使用它,为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆