Исключительный доступ не может быть получен потому, что база данных используется

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

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

Как я могу это исправить?

Ответ 1

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

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO

Теперь вы можете безнаказанно выполнить свое восстановление. Убедитесь, что вы вернули его в многопользовательский режим, когда закончите восстановление:

ALTER DATABASE [MyDB] SET Multi_User
GO

Ответ 2

Таким образом, я написал метод ниже для восстановления моей базы данных,
Я прав?

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

Лучший подход

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

  • Если указано RESTRICTED_USER, только члены db_owner, dbcreator или sysadmin могут использовать базу данных. Возврат MULTI_USER база данных в ее нормальное рабочее состояние.


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

  • свойство базы данных правой кнопкой мыши
  • перейти к опциям → последний раздел с заголовком состояния
  • изменить Ограничить доступ до SINGLE_USER
  • ответьте да на этот полезный вопрос, который показывает, что этот вид действия будет закрывать все другие соединения, и я думаю, что это единственное, что мы ищем здесь, передав ошибку

Чтобы изменить свойства базы данных, SQL Server должен закрыть все остальные соединения в базе данных. Вы действительно хотите изменить свойства и закрыть все остальные соединения? да или нет

  • восстановить базу данных
  • выполните шаг 1-4, изменив Ограничить доступ на MULTI_USER

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

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

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

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

Ответ 4

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

sqlServer.KillAllProcesses("databaseName");

Ответ 5

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

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

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

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

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

Надеюсь, что это поможет.

EDIT:

Вы также можете следовать this, чтобы узнать, откуда находятся соединения, и другую информацию:

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

ИСПОЛЬЗОВАТЬ БАЗА ДАННЫХ БАЗА ДАННЫХ МАСТЕРА ALTER SET SINGLE_USER С ROLLBACK IMMEDIATE GO

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

EXEC SP_WHO2

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

УДАЛИТЬ БАЗА ДАННЫХ DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO

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

ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO

Ответ 6

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

    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