我目前正在构建单元测试,以测试某些类是否正确编辑了 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
这部分代码进入并主动关闭所有连接,这为恢复逻辑提供了执行空间。但是,我不完全确定这是最好的方法,因为它不会阻止重新建立连接,可能会再次中断恢复过程。但到目前为止,我还没有看到证据表明这种情况已经发生。