代码之家  ›  专栏  ›  技术社区  ›  Amith George

为什么在本例中需要session.clear()来反映数据库中的更改?

  •  3
  • Amith George  · 技术社区  · 15 年前

    我有以下代码:

    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\u二级缓存和cache.use\u查询缓存都设置为false

    编辑2 :阅读 NH Documentation .

    我会不时地 执行所需的SQL语句 同步ADO.NET连接 持有物品的状态 在记忆中。这个过程,冲洗,发生 默认在以下点

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

    并在 section 10.1 上面写着,

    确保您了解 冲洗()。冲洗同步 具有内存的持久存储 更改但不更改 反之亦然 .

    那么,如何让内存中的对象得到更新呢?我了解对象是每个会话缓存的。但是执行uniqueresult()或list()应该与db同步并使缓存失效,对吗?

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

    3 回复  |  直到 6 年前
        1
  •  0
  •   Sly    15 年前

    这取决于你是什么样的运营之王。默认情况下,nhibernate具有一级缓存。它使用缓存按ID等获取实体。

        2
  •  0
  •   mattk    14 年前

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

    a接受一个ISessionFactory,并用它自己的事务范围打开它自己的会话。

    即使somefunc中使用的is session的内容被刷新到数据库中,_session也不会看到这些更改,除非清除其1级缓存。

        3
  •  0
  •   Jason Dentler    14 年前

    你有两个疗程。一个在a.somefunc中,另一个在单元测试中。每个会话在会话缓存(一级缓存)中都有自己的实体实例。会议之间没有交流或协调。当一个会话写入其更改时,不会通知另一个会话。它的会话缓存中仍然有自己过时的实例。

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