繁体   English   中英

NHibernate无状态插入行为

[英]NHibernate stateless insert behavior

我想对我在NHibernate上使用INSERT命令和无状态会话时发现的行为有一个意见(NB。我使用NHibernate 2.1.2)

情况就是这样

//STATEFULL SESSION
var session = sessionFactory.OpenSession()
using(var transaction = session.BeginTransaction()){
   var entity = new MyEntityType();
   entity.Id = 1;

   session.Save(entity);

   var entity2 = session.Get<MyEntityType>(1);  
   //OK! It returns saved entity...as I expect

   transaction.Commit();
}

但......在无国籍会议上,行为发生了变化......

//STATELESS SESSION
var session = sessionFactory.OpenStatelessSession()
using(var transaction = session.BeginTransaction()){
   var entity = new MyEntityType();
   entity.Id = 1;

   session.Insert(entity);

   var entity2 = session.Get<MyEntityType>(1);  
   //entity2 IS NULL!!! Why?

   transaction.Commit();
}

我的问题是......如何检查我是否已经在无状态会话的事务范围中插入了一个项目?

好吧,无国籍者是......无国籍的。 因此,没有会话缓存可以让您从内存中返回插入的实体。

现在,为什么不在数据库中读取? 因为它还没有出现!

您很可能已启用批处理( adonet.batch_size xml配置参数,或通过代码Environment.BatchSize配置属性,或者在会话工厂级别启用时未通过IStatelessSession.SetBatchSize(int)禁用它)。 启用批处理后,如果您的NHibernate数据库驱动程序支持它,则DML操作尽可能地一起批处理,直到配置的批处理大小,然后刷新到数据库。

因此,可以发生无状态会话的这种刷新:

  • 如果达到“批量大小”要执行的操作计数。
  • 如果提交了一个事务。
  • 如果另一个DML查询,不仅不同于其参数值,则完成。
    (在您的情况下,例如在插入后插入另一种实体,或在插入后更新或删除任何类型的实体。)
  • 通过显式刷新batcher,点击内部会话界面。
    s.GetSessionImplementation().Flush();

如果要将Insert立即发送到数据库,请禁用批处理。 将其设置为0将禁用它。

但是你为什么要首先使用无状态会话? 可能以有效的方式插入大量实体。 在这种情况下,禁用批处理将是您的目的。

因此,您可以转而使用会话GetSessionImplementation()方法公开的内部会话接口,并显式Flush它。 但是,直接调用内部可能会产生未定义的行为,因此这不是推荐的做法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM