由于数据库正在使用,无法获得专有访问权限

我正在使用以下代码来恢复数据库,

void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath) { string sRestore = "USE [master] RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + "' WITH FILE = 1, NOUNLOAD, STATS = 10"; using (SqlConnection con = new SqlConnection(ConnectionString)) { con.Open(); SqlCommand cmdBackUp = new SqlCommand(sRestore, con); cmdBackUp.ExecuteNonQuery(); } } 

但我收到以下例外

 "Exclusive access could not be obtained because the database is in use. RESTORE DATABASE is terminating abnormally. Changed database context to 'master'." 

我该如何解决?

只有当数据库没有任何连接时才能进行恢复(除了你的)。 所有用户closuresMS SQL Server上的简单方法是:

 ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate GO 

现在,你可以执行你的恢复而不受惩罚。 确保在完成恢复后将其设置回多用户模式:

 ALTER DATABASE [MyDB] SET Multi_User GO 

因此我写了下面的方法来恢复我的数据库,
我正确吗?

 void Restore(string ConnectionString, string DatabaseFullPath, string backUpPath) { using (SqlConnection con = new SqlConnection(ConnectionString)) { con.Open(); string UseMaster = "USE master"; SqlCommand UseMasterCommand = new SqlCommand(UseMaster, con); UseMasterCommand.ExecuteNonQuery(); string Alter1 = @"ALTER DATABASE [" + DatabaseFullPath + "] SET Single_User WITH Rollback Immediate"; SqlCommand Alter1Cmd = new SqlCommand(Alter1, con); Alter1Cmd.ExecuteNonQuery(); string Restore = @"RESTORE DATABASE [" + DatabaseFullPath + "] FROM DISK = N'" + backUpPath + @"' WITH FILE = 1, NOUNLOAD, STATS = 10"; SqlCommand RestoreCmd = new SqlCommand(Restore, con); RestoreCmd.ExecuteNonQuery(); string Alter2 = @"ALTER DATABASE [" + DatabaseFullPath + "] SET Multi_User"; SqlCommand Alter2Cmd = new SqlCommand(Alter2, con); Alter2Cmd.ExecuteNonQuery(); labelReport.Text = "Successful"; } } 

最好的办法

 Alter Database <Db_Name> SET [SINGLE_USER | RESTRICTED_USER] With ROLLBACK [IMMEDIATE | AFTER 30] go --do your job that needs exclusive access go --Back to normal mode Alter Database <Db_Name> SET MULTI_USER 
  • WITH ROLLBACK IMMEDIATE – 此选项不等待事务完成,只是开始回滚所有打开的事务
  • 在nnn之后使用ROLLBACK – 此选项将在等待nnn秒后等待打开的事务完成回滚所有打开的事务。 在我们的例子中,我们指定在回滚任何打开的事务之前,进程应该等待30秒。

  • 当指定RESTRICTED_USER时 ,只有db_owner,dbcreator或sysadminangular色的成员可以使用该数据库。 MULTI_USER将数据库返回到正常的操作状态。


第二种方法:使用ssms 2008 R2我们可以做同样的事情

  1. 右键单击数据库属性
  2. 转到选项 – > 状态标题的最后一节
  3. 更改限制访问 SINGLE_USER
  4. 回答是这个有帮助的问题,这表明这种行动将closures所有其他连接 ,我想这是唯一的事情,我们正在寻找这里通过错误

要更改数据库属性,SQL Server 必须closures到数据库的所有其他连接 。 您确定要更改属性并closures所有其他连接吗? 是或否

  1. 恢复你的数据库
  2. 请执行步骤1-4将限制访问权限更改回MULTI_USER

第三种方式:以下命令也将closures所有连接。

 ALTER DATABASE [DbName] SET OFFLINE go ALTER DATABASE [DbName] SET ONLINE 

现在数据库已准备好进行恢复

更多( mssqltips:获取独占访问来还原SQL Server数据库 )

可以使用SMO SqlServer对象上的方法在执行还原之前删除指定数据库上的所有进程:

 sqlServer.KillAllProcesses("databaseName"); 

这个问题的原因是不言而喻的(连接到数据库目前打开/活动),但使用以下(谷歌它,所以你理解),它会没事的:

 Alter Database YOURDB SET SINGLE_USER With ROLLBACK IMMEDIATE GO 

显然,将YOURDDBreplace为数据库的名称,然后在主数据库上运行。

噢,如果你在单用户模式下被卡住了,那么这个方法就可以解除它:

 Alter Database YOURDB SET MULTI_USER With ROLLBACK IMMEDIATE GO 

希望这可以帮助。

编辑:

您也可以按照此处,查看连接来自哪里,以及其他信息:

我testing这个服务运行时,将重新连接到数据库。 我发现你必须设置为单用户模式,然后运行sp_who2来查看一个连接来自哪里,并记下SPID。 您可以在同一事务中运行该SPID的kill命令和恢复,并且应该通过。 这是我使用的序列:

使用MASTER ALTER DATABASE DATABASENAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE GO

这将使得只有一个连接到数据库可以做。 – 运行以下命令查看数据库重复连接的来源。

EXEC SP_WHO2

– 查看这个列表,查看DBName列。 如果列出数据库,请检查ProgramName和HostName列以查看谁正在尝试连接。 – 如果它不是服务或其他可以自动重新连接的应用程序,请记下SPID列中的数字以终止连接,并立即开始备份。 用下面的数字replaceSPID。

KILL SPID RESTORE DATABASE DATABASENAME FROM DISK ='X:\ PATHTO \ BACKUP.BAK'GO

– 如果成功完成,我们可以将新恢复的数据库设置回多用户模式。

ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO

  • 只能build立到数据库的一个连接。 – 运行以下命令查看数据库重复连接的来源。

     EXEC SP_WHO2 
  • 检查这个列表,查看DBName列。 如果列出数据库,请检查ProgramName和HostName列以查看谁正在尝试连接。

  • 如果它不是服务或其他可以自动重新closures的应用程序,请注意SPID列中的数字以终止连接,并立即开始备份。 用下面的数字replaceSPID。

     KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO 
  • 如果成功完成,我们可以将新恢复的数据库设置回多用户模式。

     ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO