微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在内存中的SQLite db上使用NHibernate测试时出现随机错误

如何解决在内存中的SQLite db上使用NHibernate测试时出现随机错误

|| 我有一个系统,在收到消息后-将其入队(写到表中),另一个进程将轮询数据库并将其出队以进行处理。在我的自动测试中,我已经在同一过程中合并了这些操作,但是无法(从概念上)合并这两个操作的NH会话。 自然地-问题出现了。 我已经阅读了有关使sqlite-InMemory-NHibernate组合在测试环境中工作的一切知识,但是由于“没有此类表”错误,我现在遇到了随机失败的测试。明确地说-“随机”表示具有相同确切配置和代码的相同测试有时会失败。 我有以下sqlite配置:
return sqliteConfiguration
 .Standard
 .ConnectionString(x => x.Is(\"Data Source=:memory:; Version=3; New=True; Pooling=True; Max Pool Size=1;\"))
 .Raw(NHibernate.Cfg.Environment.ReleaseConnections,\"on_close\");
在测试(每次测试)开始时,我获取\“ static \”会话提供程序,并请其将现有的数据库清除干净,并重新创建模式:
public void PurgeDatabaSEOrCreateNew()
{
    using (var session = GetNewSession())
    using (var tx = session.BeginTransaction())
    {
            PurgeDatabaSEOrCreateNew(session);
            tx.Commit();
    }
}

private void PurgeDatabaSEOrCreateNew(ISession session)
{
    //http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx
    new SchemaExport(_Configuration)
        .Execute(false,true,false,session.Connection,null);
}
因此,是的,它在不同的会话上,但是连接是在sqlite上建立的,因此我创建的下一个会话将看到生成的架构。但是,尽管大多数情况下它都起作用,但有时以后的“入队”操作将失败,因为它看不到我收到的消息的表。 另外-这似乎在每次测试套件运行中最多发生一两次。并非所有测试都失败了,只有第一个测试失败了(有时还会失败。有时不确定是否是第二个)。 自然,最糟糕的部分是随机性。我已经告诉自己我已经修复了好几次,只是因为它只是“停止了失败”。随意地。 在TestDriven.NET 32b进项和NUnit控制台32b进程上,在FW4.0,System.Data.sqlite x86版本,Win7 64b和2008R2(总共三台不同的机器),配置有FNH的NH2.1.2上会发生这种情况。 救命?     

解决方法

嗨,我很确定我和您有同样的问题。每个集成测试我打开和关闭多个会话。在深入研究了SQLite连接池并进行了一些我自己的尝试之后,我得出以下结论: SQLite池代码使用WeakReferences来缓存连接,这不是缓存的最佳选择,因为当没有正常(强)的连接引用且GC运行时,将清除对连接的引用。由于您无法预测GC的运行时间,因此可以解释“随机性”。尝试在关闭一个会话与打开另一个会话之间添加“ 2”,您的测试将始终失败。 我的解决方案是在打开的会话之间自己缓存连接,如下所示:
public class BaseIntegrationTest
{
    private static ISessionFactory _sessionFactory;
    private static Configuration _configuration;
    private static SchemaExport _schemaExport;

    // I cache the whole session because I don\'t want it and the
    // underlying connection to get closed.
    // The \"Connection\" property of the ISession is what we actually want.
    // Using the NHibernate SQLite Driver to get the connection would probably
    // work too.
    private static ISession _keepConnectionAlive;

    static BaseIntegrationTest()
    {
        _configuration = new Configuration();
        _configuration.Configure();
        _configuration.AddAssembly(typeof(Product).Assembly);
        _sessionFactory = _configuration.BuildSessionFactory();
        _schemaExport = new SchemaExport(_configuration);

        _keepConnectionAlive = _sessionFactory.OpenSession();
    }

    [SetUp]
    protected void RecreateDB()
    {
        _schemaExport.Execute(false,true,false,_keepConnectionAlive.Connection,null);
    }

    protected ISession OpenSession()
    {
        return _sessionFactory.OpenSession(_keepConnectionAlive.Connection);
    }
}
我的每个集成测试都继承自此类,并调用OpenSession()来获取会话。由于[SetUp]属性,在每次测试之前NUnit都会调用RecreateDB。 希望这对您或其他收到此错误的人有所帮助。     ,唯一会想到的是,您在测试后会随机打开会话。打开另一个ISession之前,必须确保已将其关闭。如果您没有使用using()语句或手动调用Dispose(),则该会话可能仍处于活动状态,从而导致这些随机异常。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?