由于数据库正在使用,因此无法获得独占访问权限

时间:2010-10-28 19:59:05

标签: c# sql tsql database-restore

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

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'."

我该如何解决?

6 个答案:

答案 0 :(得分:52)

只有在数据库没有任何连接时(除了你的数据库),才能进行恢复。 MS SQL Server上关闭所有用户的简便方法是:

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO

现在,您可以执行恢复而不受惩罚。完成恢复后,请确保将其重新设置为多用户模式:

ALTER DATABASE [MyDB] SET Multi_User
GO

答案 1 :(得分:14)

因此我写了以下方法来恢复我的数据库,
我是对的吗?

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";
    }
}

答案 2 :(得分:9)

您可以使用SMO Sql Server对象上的方法在执行还原之前终止指定数据库上的所有进程:

sqlServer.KillAllProcesses("databaseName");

答案 3 :(得分:8)

最好的方法

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 
  • 立即回滚 - 此选项不等待进行交易 完成它只是开始回滚所有未结交易
  • 在nnn之后使用ROLLBACK - 此选项将全部回滚 交易等待nnn秒以进行打开的交易 完成。在我们的示例中,我们指定了该过程 在回滚任何未结交易之前等待30秒。

  • 指定 RESTRICTED_USER 时,只有 db_owner的成员, dbcreator或sysadmin 角色可以使用该数据库。 MULTI_USER返回 数据库处于正常运行状态。


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

  1. 右键单击数据库属性
  2. 转到选项 - &gt;标题为 state
  3. 的最后一部分
  4. 限制访问权限更改为 SINGLE_USER
  5. 对这个有用的问题回答“是”,这个问题表明这种行为将关闭所有其他连接,我想这是我们通过传递错误唯一能找到的内容
  6.   

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

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

    3. 第三种方式:以下命令也将关闭所有连接。

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

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

      更多(mssqltips :Getting exclusive access to restore SQL Server databases

答案 4 :(得分:1)

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

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

显然,将YOURDDB替换为数据库的名称,并针对主数据库运行该命令。

哦,只是如果你在单用户模式下“卡住”,这将取消它:

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

希望这有帮助。

编辑:

您还可以关注this,查看连接的来源以及其他信息:

  

我在提供服务时对此进行了测试   运行,将重新连接到   数据库。我发现你必须设置   单用户模式,然后运行sp_who2到   看看一个连接在哪里   来自,并注意到SPID。您   可以为该SPID运行kill命令   和恢复相同   交易,它应该通过。   这是我使用的序列:

     

使用MASTER ALTER DATABASE DATABASENAME   使用ROLLBACK设置SINGLE_USER   立即开始

     

- 这样就可以实现与数据库的一个连接   制作。    - 运行以下命令以查看任何重复连接的位置   数据库来自。

     

EXEC SP_WHO2

     

- 查看此列表,查看DBName列。如果数据库是   列出,检查ProgramName,和   HostName列,以查看谁是   试图连接。    - 如果它不是服务或其他自动应用程序   重新连接,可以关闭,请注意   要杀死的SPID列中的数字   连接,并立即开始   备份。将以下SPID替换为   只是数字。

     

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

     

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

     

ALTER DATABASE DATABASENAME SET   带有ROLLBACK IMTIEDIATE的MULTI_USER GO

答案 5 :(得分:1)

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

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

  • 如果它不是可以自动重新连接的服务或其他可以关闭的应用程序,请记下SPID列中的数字以终止连接,并立即开始备份。仅使用数字替换下面的SPID。

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

    ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO