代码之家  ›  专栏  ›  技术社区  ›  Mohammad Dayyan

无法获得独占访问,因为数据库正在使用中

  •  35
  • Mohammad Dayyan  · 技术社区  · 14 年前

    我正在使用以下代码还原数据库,

    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 回复  |  直到 14 年前
        1
  •  52
  •   KeithS    11 年前

    只有当数据库没有任何连接(除了您的连接)时,才能进行还原。在MS-SQL服务器上,让所有用户离开的简单方法是:

    ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
    GO
    

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

    ALTER DATABASE [MyDB] SET Multi_User
    GO
    
        2
  •  14
  •   Mohammad Dayyan    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";
        }
    }
    
        3
  •  9
  •   Iman    12 年前

    最佳方法

    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之后回滚 交易 等待nnn秒后 完成。在我们的示例中,我们指定流程应该 在回滚任何打开的事务之前,请等待30秒。

    • 什么时候? 已指定,只有 数据库所有者, dbcreator或sysadmin 角色可以使用数据库。多用户返回 数据库恢复到正常操作状态。


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

    1. 转到“选项”->“页眉为的最后一节”
    2. 改变 单用户
    3. 回答“是”这个有用的问题,它表明这种行为 关闭所有其他连接 我想这是我们在这里唯一希望通过错误

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

    1. 还原数据库
    2. 限制访问 回到 多用户

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

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

    现在数据库已准备好还原

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

        4
  •  9
  •   bluish dmajkic    11 年前

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

    sqlServer.KillAllProcesses("databaseName");
    
        5
  •  1
  •   Dave    14 年前

    这个问题的原因是不言而喻的(与当前打开/活动的数据库的连接),但是使用以下内容(也可以用google搜索它,以便您理解它)就可以了:

    Alter Database YOURDB   
    SET SINGLE_USER With ROLLBACK IMMEDIATE
    GO
    

    YOURDDB 使用数据库的名称并对主数据库运行它。

    哦,如果你让它“卡”在单用户模式,这会撤销它:

    Alter Database YOURDB   
    SET MULTI_USER With ROLLBACK IMMEDIATE
    GO
    

    编辑:

    你也可以跟着 this ,以查看连接的来源和其他信息:

    我在服务的时候测试过这个 运行将重新连接到 数据库。我发现你必须 看看那个连接在哪里 从,并注意到SPID。你 可以为那个SPID运行kill命令 恢复原状 以下是我使用的序列:

    使用MASTER ALTER数据库数据库名称 使用回滚设置单个用户

    -这将使得只有一个到数据库的连接可以 制造的。 -运行以下命令以查看到 数据库来自。

    执行SP_WHO2

    列出,检查程序名,然后 主机名列以查看 -如果不是服务或其他应用程序 重新连接可关闭,注意 要杀死的SPID列中的数字 后援。将下面的SPID替换为 只有号码。

    来自磁盘的数据库名= 'X:\路径到\备份.BAK'GO

    回到多用户模式。

    带回滚立即转到的多用户

        6
  •  1
  •   kleopatra Aji kattacherry    11 年前
    • 只能与数据库建立一个连接。-运行以下命令以查看到数据库的任何定期连接的来源。

      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