在单元测试下恢复SQL Server时避免恢复卡住

时间:2012-08-29 12:20:24

标签: c# unit-testing sql-server-2005

我目前正在构建单元测试,测试某些类是否正确编辑sql server 2005数据库。为此,我从我们的生产中创建了一小部分数据,并将其存储为备份文件。每当单元测试需要确保它具有干净的数据库状态时,它会调用一个基本上调用以下sql的恢复例程:

RESTORE DATABASE database FROM DISK = 'c:\test\backup.bak' WITH REPLACE, NORECOVERY

这通常有效,速度也不错。当我正常说它时,因为有时数据库会陷入“恢复”状态。模式导致错误消息看起来像这样(假设它是一个Alter命令):

ALTER DATABASE is not permitted while a database is in the Restoring state.

这意味着如果第一次失败,则每次测试都会失败。我可以将数据库从卡住状态中解脱出来,但每次都这样做会非常烦人,这非常耗费时间,而且单元测试的全部要点都是如此我不需要我激活测试的任何事情。

我试着看看我是否可以通过RESTORE语法来避免它,但是不能解决听起来像是可以解决问题的任何选项或标志。

我还能使用哪种方法比RESTORE命令更安全吗?

更新 我发现恢复失败主要发生在连接仍处于活动状态时。我通常使用以下结构处理该问题:

ALTER DATABASE MyDatabase SET Single_User WITH Rollback Immediate

-- Restore logic here

ALTER DATABASE MyDatabase SET Multi_User

这个问题是它只将所有连接限制为一个。有时,其中一个被迫关闭的连接会跳转到唯一一个可用的连接,破坏恢复并使其失败(或者我可以从我正在阅读的文档和页面中收集这些内容)。

我在开始恢复逻辑之前尝试执行以下SQL命令:

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id('Mydatabase')
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id('Mydatabase') and spid > @spid
End

-- Do Restore Logic

http://geekswithblogs.net/AngelEyes/archive/2010/02/24/kill-connections-to-resote-db---sql-server.aspx

这部分代码进入并主动关闭所有连接,这使得恢复逻辑空间能够执行。但是,我并不完全确定这是最好的方法,因为它不会阻止连接重新建立,可能会再次破坏恢复过程。但到目前为止,我还没有看到证据表明这种情况已经发生了。

2 个答案:

答案 0 :(得分:0)

我发现成功的方法是首先回滚数据库然后删除它,以解决已经打开或链接到的任何问题:

if db_id('MyDatabase') is not null ALTER DATABASE MyDatabase SET SINGLE_USER 
    WITH ROLLBACK  IMMEDIATE

if db_id('MyDatabase') is not null drop database MyDatabase

create database MyDatabase

答案 1 :(得分:0)

通过使用usr的建议和脚本完成恢复过程,我得到了它的工作。这个答案是关闭这个问题所以访问者知道我找到了解决方案。该解决方案在原始问题中描述为更新。