为什么session.Clear()需要反映此示例中db的更改?

时间:2010-06-18 15:22:44

标签: nhibernate session

我有以下代码:

public class A
{
    private ISessionFactory _sf;
    A(ISessionFactory sf)
    {
        _sf = sf;
    }

    public void SomeFunc()
    {
        using (var session = _sf.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            // query for a object
            // change its properties
            // save the object

            transaction.commit();
        }
    }
}

在单元测试中使用如下

_session.CreateCriteria ... // some setting up values for this test

var objectA = new A(_sessionFactory);
objectA.SomeFunc();

// _session.Clear();

var someVal = _session.CreateCriteria ... // retrieve value from db to 
                                   //check if it was set to the 
                                   //proper value
                                   //it uses a restriction on a property
                                   //and a uniqueresult to get the object.
                                   //it doesnt use get or load.

Assert.That(someVal, Is.EqualTo(someOtherValue)); // this is false as long 
                                   //as the _session.Clear() is commented. 
                                   //If uncommented, the test passes

我正在测试 sqlite文件数据库。在我的测试中,我对数据库进行了一些更改以正确设置它。然后我调用SomeFunc()。它进行了必要的修改。一旦我回到测试中,会话就不会获得更新的值。它仍然返回调用SomeFunc()之前的值。我必须执行_session.Clear()以使更改反映在我在测试中的断言中。

为什么需要这个?

编辑:cache.use_second_level_cache和cache.use_query_cache都设置为false

Edit2 :阅读NH Documentation

中的以下语句
  

ISession会不时地   执行所需的SQL语句   同步ADO.NET连接   持有对象状态的状态   在记忆中。发生此过程,冲洗   默认情况下,在以下几点

* from some invocations of Find() or Enumerable()
* from NHibernate.ITransaction.Commit()
* from ISession.Flush()

section 10.1中,它说,

  

确保你理解的语义   同花顺()。刷新同步   内存中的持久存储   更改但不是反之亦然

那么,我如何让内存对象得到更新?我知道每个会话都会缓存对象。但是执行UniqueResult()或List()应该与db同步并使缓存无效,对吗?

我无法理解的是,为什么会话报告陈旧数据?

3 个答案:

答案 0 :(得分:0)

这取决于你做了什么样的操作。 NHibernate默认具有一级缓存。它使用缓存来按ID获取实体,依此类推。

答案 1 :(得分:0)

对象的内存视图(1级缓存)是每个会话。

A接受ISessionFactory并使用自己的事务范围打开自己的会话。

即使SomeFunc中使用的ISession的内容被刷新到数据库,_session也不会看到这些更改,直到它的1级缓存被清除。

答案 2 :(得分:0)

你有两个会话。一个是A.SomeFunc,另一个是你的单元测试。每个会话在会话缓存(第一级缓存)中都有自己的实体实例。会话不会相互通信或协调。当一个会话写入其更改时,不会通知另一个会话。它的会话缓存中仍然有自己过时的实例。

当您调用_session.Clear()时,通过清除会话缓存使会话“忘记”。当您重新查询时,您正在从数据库中读取新数据,其中包括来自其他会话的更改。