我目前正在构建单元测试,以测试某些类是否正确编辑了 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
这段代码进去主动关闭所有连接,给恢复逻辑留有执行空间。但是,我并不完全确定这是最好的方法,只是因为它不会阻止重新建立连接,可能会再次中断恢复过程。但到目前为止,我还没有看到这已经发生的证据。
最佳答案
我发现成功的方法是首先回滚数据库,然后删除它,这样可以解决已经打开或链接到的任何问题:
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
关于c# - 单元测试下恢复SQL Server时避免恢复卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12177818/