为什么调用 NHibernate AdoTransaction 的终结器?

发布于 2024-07-25 01:50:48 字数 2288 浏览 6 评论 0原文

我正在分析单位和 集成测试,我发现很多时间都花在 NHibernate.Transaction.AdoTransaction 的终结器上 - 这意味着它没有得到正确的处理。

我没有直接在代码中使用 AdoTransaction,因此它可能被 NHibernate 中的其他对象使用。 知道我忘记丢弃什么吗?

这是我的文本装置:

public abstract class AbstractInMemoryFixture
{
    protected ISessionFactory sessionFactory;
    protected ILogger Logger { get; private set; }
    static readonly Configuration config;
    private static readonly ISessionFactory internalSessionFactory;

    static AbstractInMemoryFixture()
    {
        config = new NHibernateConfigurator().Configure(NHibernateConfigurators.SQLiteInMemory());
        internalSessionFactory = config.BuildSessionFactory();
    }

    [SetUp]
    public void SetUp()
    {
        const string sqliteInMemoryConnectionString = "Data Source=:memory:;Version=3;Pooling=False;Max Pool Size=1;";
        var con = new SQLiteConnection(sqliteInMemoryConnectionString);
        con.Open();
        new SchemaExport(config).Execute(false, true, false, true, con, System.Console.Out);
        var proxyGenerator = new ProxyGenerator();

        sessionFactory = proxyGenerator.CreateInterfaceProxyWithTarget(internalSessionFactory, new UseExistingConnectionInterceptor(con));
        Logger = new NullLogger();

        ExtraSetup();
    }

    [TearDown]
    public void TearDown()
    {
        var con = sessionFactory.OpenSession().Connection;
        if (con != null)
        {
            if (con.State == ConnectionState.Open)
                con.Close();
            con.Dispose();
        }
    }

    private class UseExistingConnectionInterceptor :IInterceptor
    {
        private readonly SQLiteConnection connection;

        public UseExistingConnectionInterceptor(SQLiteConnection connection)
        {
            this.connection = connection;
        }

        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.Name != "OpenSession" || invocation.Method.GetParameters().Length > 0)
            {
                invocation.Proceed();
                return;
            }
            var factory = (ISessionFactory) invocation.InvocationTarget;
            invocation.ReturnValue = factory.OpenSession(connection);
        }
    }
    protected virtual void ExtraSetup() { }
}

I'm profiling out unit & integration tests, and I find the a lot of the time is spent on the finalizer of NHibernate.Transaction.AdoTransaction - this means it is not getting disposed properly.

I am not using AdoTransaction directly in the code, so it's probably used by some other object inside NHibernate. Any idea what I'm forgetting to Dispose?

Here is my text fixture:

public abstract class AbstractInMemoryFixture
{
    protected ISessionFactory sessionFactory;
    protected ILogger Logger { get; private set; }
    static readonly Configuration config;
    private static readonly ISessionFactory internalSessionFactory;

    static AbstractInMemoryFixture()
    {
        config = new NHibernateConfigurator().Configure(NHibernateConfigurators.SQLiteInMemory());
        internalSessionFactory = config.BuildSessionFactory();
    }

    [SetUp]
    public void SetUp()
    {
        const string sqliteInMemoryConnectionString = "Data Source=:memory:;Version=3;Pooling=False;Max Pool Size=1;";
        var con = new SQLiteConnection(sqliteInMemoryConnectionString);
        con.Open();
        new SchemaExport(config).Execute(false, true, false, true, con, System.Console.Out);
        var proxyGenerator = new ProxyGenerator();

        sessionFactory = proxyGenerator.CreateInterfaceProxyWithTarget(internalSessionFactory, new UseExistingConnectionInterceptor(con));
        Logger = new NullLogger();

        ExtraSetup();
    }

    [TearDown]
    public void TearDown()
    {
        var con = sessionFactory.OpenSession().Connection;
        if (con != null)
        {
            if (con.State == ConnectionState.Open)
                con.Close();
            con.Dispose();
        }
    }

    private class UseExistingConnectionInterceptor :IInterceptor
    {
        private readonly SQLiteConnection connection;

        public UseExistingConnectionInterceptor(SQLiteConnection connection)
        {
            this.connection = connection;
        }

        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.Name != "OpenSession" || invocation.Method.GetParameters().Length > 0)
            {
                invocation.Proceed();
                return;
            }
            var factory = (ISessionFactory) invocation.InvocationTarget;
            invocation.ReturnValue = factory.OpenSession(connection);
        }
    }
    protected virtual void ExtraSetup() { }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧情勿念 2024-08-01 01:50:48

我在访问 Sybase 数据库时遇到同样的问题。 我不知道为什么,也不知道这是否真的是问题的原因,但似乎 \NHibernate\Transaction\AdoTransaction.cs(第 307 至 311 行)与关闭/处置对象相关的操作已被禁用一段时间。 不幸的是,SVN 的指责功能没有提供太多信息:(

I have the same problem while accessing a Sybase database. I don't know why, nor if it's really the reason of the issue, but it appears that some of the code in \NHibernate\Transaction\AdoTransaction.cs (lines 307 to 311) related to closing/disposing the object have been disabled for a while. Unfortunately, the blame feature of SVN does not give too much info :(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文