如何在集成测试中自动关闭从IIS进行数据库重建的SQL Server连接

本文关键字:数据库 重建 连接 Server SQL IIS 集成测试 | 更新日期: 2023-09-27 18:10:30

我正在通过WinForms和WebService玩一些DB连接,我发现使用web服务时连接没有关闭。这会在我的自动化测试中导致一个小故障,因为我在测试之间销毁并重新创建数据库,所以我总是对每个测试具有相同的启动状态。

调用的实际数据访问代码在两种情况下是相同的,例如:

            using (DataHandler handler = new DataHandler(Config.ConnectionString()))
        {
            return handler.GetDbVersion();
        }

DataHandler使用一个数据上下文(使用SqlMetal创建)从DB表中加载一个整数并返回它。

DataHandler的Dispose方法关闭连接和数据上下文:

    public void Dispose()
    {
        _data.Connection.Close();
        _data.Connection.Dispose();
        _data.Dispose();
    }

当直接从单元测试中运行时-这将贯穿并且之后DB上没有任何连接。

select spid, status, loginame, hostname, blocked, db_name(dbid), cmd from master..sysprocesses where db_name(dbid) = 'TEST_DATABASE'

然后我把它包装在一个[WebMethod]中,并把它放在一个IIS7实例中:

    [WebMethod]
    public int GetDatabaseVersionNumber()
    {
        using (DataHandler handler = new DataHandler(Config.ConnectionString()))
        {
            return handler.GetDbVersion();
        }
    }

测试调用web服务:

        int dbVersion = _webService.GetDatabaseVersionNumber();

web服务创建数据上下文-获取号码-调用Dispose,然后返回号码。然而,连接仍然在DB中"睡眠"。这意味着当我尝试销毁并重新创建数据库以进行下一次测试时,删除数据库失败(活动连接)。

select spid, status, loginame, hostname, blocked, db_name(dbid), cmd from master..sysprocesses where db_name(dbid) = 'TEST_DATABASE'
54  sleeping IIS APPPOOL'ASP.NET v4.0   PETE    0   TEST_DATABASE   AWAITING COMMAND

我假设这是IIS和SQL Server处理的某种连接池,以减少从web请求打开和关闭连接的开销(我想我不想在部署web服务的上下文中弄乱这个)

但是,对于测试,我希望终止此连接,以便可以重新构建数据库。

处理这个问题的最好方法是什么?(这是我需要在IIS中设置的东西,还是在测试数据库中?我可以在连接字符串中定义它,所以它只发生在测试上吗?)

为信息

通过在test teardown方法中添加以下代码解决:

            if (data.DatabaseExists())
        {
            data.ExecuteCommand("ALTER DATABASE TEST_DATABASE SET SINGLE_USER WITH ROLLBACK IMMEDIATE;");
            data.ExecuteCommand("ALTER DATABASE TEST_DATABASE SET MULTI_USER;");
            data.DeleteDatabase();              
        }   

更新

我发现我可以通过在单元测试应用程序配置中的连接字符串中添加"Pooling=false"来绕过这个问题。这似乎比强制关闭连接要好得多,因为当你强制关闭它们时,有时数据库不能用于套件的下一个测试(你会得到一个"管道另一端没有服务"类型错误,因为SQL已经消失,但。net认为它仍然存在)。

如何在集成测试中自动关闭从IIS进行数据库重建的SQL Server连接

您总是可以运行alter database命令并将其设置为立即回滚的单用户。这将终止所有连接,以便您删除数据库,或执行任何您想要的任务。

检查SQL Server连接池状态

ADO。NET 2.0引入了两种新的方法来清除池:ClearAllPools和ClearPool。ClearAllPools清除连接池对于一个给定的提供者,ClearPool清除连接池与特定连接相关联。如果有连接在使用在呼叫时,它们被适当地标记。当他们关闭后,它们将被丢弃,而不是返回到池中。