No se pudo obtener acceso exclusivo porque la base de datos está en uso


Estoy usando el siguiente código para restaurar bases de datos,

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();
    }
}

Pero recibo la siguiente excepción

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

¿Cómo puedo arreglarlo ?

Author: Brad, 2010-10-28

6 answers

Una restauración solo puede ocurrir si la base de datos no tiene ninguna conexión con ella (además de la suya). La manera fácil en un servidor de MS SQL para patear a todos los usuarios es:

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO

Ahora, usted puede realizar su restauración con impunidad. Asegúrese de volver a configurarlo en modo multiusuario cuando haya terminado con la restauración:

ALTER DATABASE [MyDB] SET Multi_User
GO
 49
Author: KeithS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-14 18:09:31

Así que he escrito el siguiente método para restaurar mi base de datos,
Estoy en el camino correcto ?

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";
    }
}
 14
Author: Mohammad Dayyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-29 02:55:13

El mejor enfoque

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 
  • CON REVERSIÓN INMEDIATA - esta opción no espera para las transacciones para completarlo simplemente comienza a revertir todas las transacciones abiertas
  • CON REVERSIÓN DESPUÉS DE nnn - esta opción revertirá todo abierto transacciones después de esperar nnn segundos para las transacciones abiertas a completo. En nuestro ejemplo estamos especificando que el proceso debe espere 30 segundos antes de revertir cualquier transacción abierta.

  • Cuando se especifica RESTRICTED_USER, solo los miembros del db_owner, los roles dbcreator o sysadmin pueden usar la base de datos. Devoluciones MULTI_USUARIO la base de datos a su estado de funcionamiento normal.


2da manera: usando ssms 2008 R2 podemos hacer lo mismo

  1. haga clic con el botón derecho en la propiedad de la base de datos
  2. vaya a opciones- > última sección con encabezado de estado
  3. change Restrict Access to SINGLE_USER
  4. responder sí a esta pregunta útil que muestra que este tipo de acción cerrará todas las demás conexiones y supongo que es lo único que estamos buscando aquí para pasar el error

Para cambiar las propiedades de la base de datos, SQL Server debe cerrar todas las demás conexiones a la base de datos. Está seguro de que desea cambiar las propiedades y cerrar todas las demás conexiones? sí o no

  1. restaura tu base de datos
  2. do paso 1-4 cambiar Restringir el acceso volver a MULTI_USUARIO

3rd way: los siguientes comandos también cerrarán todas las conexiones.

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

Ahora la base de datos está lista para restaurar

Más (mssqltips: Obtener acceso exclusivo para restaurar bases de datos de SQL Server )

 8
Author: Iman Abidi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-10 21:19:00

Puede usar el método en el objeto SMO SQLServer para kiil todos los procesos en una base de datos especificada antes de realizar una restauración:

sqlServer.KillAllProcesses("databaseName");
 7
Author: Martin Bell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-14 14:17:36

La razón de este problema es evidente (conexiones a la base de datos actualmente abiertas/activas), pero use lo siguiente (google también para que lo entienda) y estará bien:

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

Obviamente, reemplace YOURDDB con el nombre de su base de datos y ejecútelo contra la base de datos maestra.

Oh, y por si acaso, si lo consigues 'atascado' en modo de usuario único, esto lo deshará:

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

Espero que esto ayude.

EDITAR:

También puedes seguir esto , para ver dónde las conexiones son de, y otra información:

Probé esto mientras tenía servicios que se reconectaría a la base. Me di cuenta de que tenía que establecer a Modo de Usuario Único, luego ejecute sp_who2 para ver dónde estaba la única conexión viniendo de, y fíjate en la ARAÑA. Usted puede ejecutar el comando kill para ese SPID y la restauración en el mismo transacción, y debería pasar. Aquí está la secuencia que usé:

USE MASTER ALTER DATABASE DATABASENAME ESTABLECER SINGLE_USER CON REVERSIÓN INMEDIATO IR

- Esto hará que solo una conexión a la base de datos pueda ser hecho. - Ejecute el siguiente comando para ver donde las conexiones recurrentes a la base de datos viene de.

EXEC SP_WHO2

-Compruebe esta lista, mirando debajo de la columna DBName. Si la base de datos es listed, compruebe el nombre del programa, y Columna Nombre de HOST para ver quién es intentando conectar. -Si no se trata de un servicio, u otra aplicación que automática volver a conectar que se puede apagar, nota el número en la columna SPID a matar la conexión, e inmediatamente comenzar copia. Reemplazar SPID abajo con sólo el número.

MATAR A SPID RESTAURAR LA BASE DE DATOS DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK ' GO

- Si esto se completa con éxito, podemos establecer la base de datos recién restaurada volver al modo multiusuario.

ALTER DATABASE DATABASENAME SET MULTI_USUARIO CON REVERSIÓN INMEDIATA GO

 1
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 20:26:07
  • Solo se puede hacer una conexión a la base de datos. - Ejecute el siguiente comando para ver de dónde vienen las conexiones recurrentes a la base de datos.

    EXEC SP_WHO2
    
  • Compruebe esta lista, mirando debajo de la columna DBName. Si la base de datos aparece en la lista, marque la columna Nombre de programa y nombre de HOST para ver quién está intentando conectarse.

  • Si no se trata de un servicio, u otra aplicación que se reconecta automáticamente que se puede apagar, tenga en cuenta el número en el SPID columna para matar la conexión, e inmediatamente comenzar la copia de seguridad. Reemplace SPID a continuación con solo el número.

    KILL SPID RESTORE DATABASE DATABASENAME FROM DISK = 'X:\PATHTO\BACKUP.BAK' GO
    
  • Si esto se completa con éxito, podemos volver a configurar la base de datos recién restaurada en modo multiusuario.

    ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO
    
 1
Author: karthik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-10 09:48:32