Не удалось получить эксклюзивный доступ, поскольку база данных используется

Я использую следующий код для восстановления баз данных

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 ответов


восстановление может произойти только в том случае, если база данных не имеет никаких связей (кроме вас). Простой способ на сервере MS SQL выгнать всех пользователей:

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 
  • С ОТКАТОМ НЕМЕДЛЕННО - этот параметр не ждать для сделок для его завершения просто начинается откат всех открытых транзакций
  • с откатом после nnn - эта опция откатит все открытые сделок после ожидания NNN секунд для открытых проводок полный. В нашем примере мы указываем, что процесс должен подождите 30 секунд перед откатом любых открытых транзакций.

  • , когда предложение restricted_user указывается, только члены базы данных db_owner, dbcreator или sysadmin роли могут использовать базу данных. Multi_user возвращает база данных в нормальном рабочем состоянии.


2-й способ: используя ssms 2008 R2, мы можем сделать то же самое

  1. щелкните правой кнопкой мыши свойство базы данных
  2. перейти к опции - > последний раздел с заголовок государство
  3. изменить Ограничить Доступ К to single_user указан
  4. ответить " да " на этот полезный вопрос, который показывает, что такого рода действия будут закрыть все другие подключения и я думаю, это единственное, что мы ищем здесь, чтобы передать ошибку

чтобы изменить свойства базы данных, SQL Server необходимо закрыть все другие подключения в базу данных. Вы вы уверены, что хотите изменить свойства и закрыть все остальные соединения? да или нет!--3-->

  1. восстановить базу данных
  2. сделайте шаг 1-4 изменение Ограничить Доступ К на MULTI_USER

3-й способ: следующие команды также закроют все соединения.

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

теперь база данных готова для восстановления

больше (mssqltips: получение эксклюзивного доступа для восстановления Базы данных SQL Server)


вы можете использовать метод на объекте SMO SqlServer для kiil всех процессов в указанной базе данных перед выполнением восстановления:

sqlServer.KillAllProcesses("databaseName");

причина этой проблемы очевидна (соединения с базой данных в настоящее время открыты / активны), но используйте следующее (google тоже, чтобы вы это поняли), и все будет хорошо:

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

очевидно, что заменить YOURDDB С именем вашей базы данных и запустите это против главной БД.

О, и просто incase, если вы получите его "застрял" в однопользовательском режиме, это отменит его:

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

надеюсь, что это помогает.

EDIT:

вы можете также следуйте этой, чтобы увидеть, где соединения от, и другая информация:

Я проверил это, имея услуги запуск, который будет повторно подключаться к база данных. Я нашла тебя было установлено Однопользовательский режим, затем запустите sp_who2 для посмотрите, где была одна связь и обратите внимание на СПИД. Вы может запустить команду kill для этого SPID и восстановление в том же сделка, и она должна пройти. Вот последовательность I используется:

ИСПОЛЬЗОВАТЬ ИМЯ БАЗЫ ДАННЫХ MASTER ALTER DATABASE НАБОР SINGLE_USER УКАЗАН С ОТКАТА НЕМЕДЛЕННОЕ GO

- это сделает так, что только одно соединение с базой данных может быть сделанный. -Выполните следующую команду, чтобы увидеть, где любые повторяющиеся соединения база данных поступает из.

EXEC SP_WHO2

-проверьте этот список, заглянув под столбец DBName. Если база данных в списке, проверьте имя программы, и Столбец HostName, чтобы узнать, кто есть попытка подключения. -Если это не служба, или другое приложение, которое будет автоматически reconnect который можно выключить, Примечание число в столбце SPID, чтобы убить соединение, и немедленно начните резервная копия. Заменить SPID ниже только номер.

УБИТЬ SPID ВОССТАНОВИТЬ БАЗУ ДАННЫХ DATABASENAME С ДИСКА = 'X:\PATHTO\BACKUP.BAK ' GO

- Если это завершится успешно, мы можем установить недавно восстановленную базу данных обратно в многопользовательский режим.

ALTER DATABASE DATABASENAME SET MULTI_USER С ОТКАТОМ НЕМЕДЛЕННО GO


  • только одно соединение с базой данных может быть сделано. - Выполните следующую команду, чтобы узнать, откуда берутся повторяющиеся соединения с базой данных.

    EXEC SP_WHO2
    
  • проверьте этот список, заглянув под столбец DBName. Если база данных указана, проверьте столбец имя программы и имя хоста, чтобы узнать, кто пытается подключиться.

  • если это не служба или другое приложение, которое будет автоматически подключаться, которое может быть завершите работу, запишите номер в столбце SPID, чтобы отключить соединение, и немедленно начните резервное копирование. Замените SPID ниже только номером.

    KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
    
  • если это завершится успешно, мы можем установить недавно восстановленную базу данных в многопользовательский режим.

    ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO