propiedad tag c#
No se pudo obtener acceso exclusivo porque la base de datos está en uso (6)
Estoy usando el siguiente código para restaurar las 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 a continuación la 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 ?
El motivo de este problema es evidente (conexiones a la base de datos actualmente abierta / activa), pero use lo siguiente (googleelo 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 con el DB maestro.
Ah, y solo en caso de que, si lo "atascas" en modo de usuario único, esto lo deshaga:
Alter Database YOURDB
SET MULTI_USER With ROLLBACK IMMEDIATE
GO
Espero que esto ayude.
EDITAR:
También puede seguir esto , para ver de dónde provienen las conexiones y otra información:
Probé esto mientras ejecutaba servicios que se volverían a conectar a la base de datos. Descubrí que tenía que establecer el modo de usuario único, luego ejecutar sp_who2 para ver de dónde provenía la conexión y observar el SPID. Puede ejecutar el comando kill para ese SPID y la restauración en la misma transacción, y debería ejecutarse. Aquí está la secuencia que utilicé:
USE MASTER ALTER DATABASE DATABASENAME SET SINGLE_USER CON ROLLBACK INMEDIATE GO
- Esto hará que solo se pueda realizar una conexión a la base de datos. Ejecute el siguiente comando para ver de dónde provienen las conexiones recurrentes a la base de datos.
EXEC SP_WHO2
-Verifique esta lista, buscando debajo de la columna DBName. Si la base de datos está en la lista, compruebe el ProgramName y la columna HostName para ver quién está intentando conectarse. -Si no se trata de un servicio u otra aplicación que se reconectaría automáticamente y se puede cerrar, anote el número en la columna SPID para cancelar la conexión e inmediatamente comience la copia de seguridad. Reemplace SPID a continuación con solo el número.
KILL SPID RESTAURAR BASE DE DATOS DATABASENAME FROM DISK = ''X: / PATHTO / BACKUP.BAK'' GO
-Si esto se completa con éxito, podemos restablecer la base de datos recién restaurada al modo multiusuario.
ALTER DATABASE DATABASENAME SET MULTI_USER CON ROLLBACK INMEDIATE GO
Por lo tanto, 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";
}
}
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 ROLLBACK INMEDIATE - esta opción no espera a que las transacciones lo completen, simplemente comienza a deshacer todas las transacciones abiertas
CON ROLLBACK DESPUÉS de nnn : esta opción revertirá todas las transacciones abiertas después de esperar nnn segundos para que se completen las transacciones abiertas. En nuestro ejemplo, estamos especificando que el proceso debe esperar 30 segundos antes de deshacer cualquier transacción abierta.
Cuando se especifica RESTRICTED_USER , solo los miembros de los roles db_owner, dbcreator o sysadmin pueden usar la base de datos. MULTI_USER devuelve la base de datos a su estado operativo normal.
2da manera: usando ssms 2008 R2 podemos hacer lo mismo
- haga clic derecho en propiedad de la base de datos
- ir a opciones -> última sección con encabezado de estado
- cambiar Restringir el acceso a SINGLE_USER
- Responda "sí" a esta útil pregunta que muestra que este tipo de acción cerrará todas las demás conexiones y supongo que es lo único que estamos buscando 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. ¿Seguro que quieres cambiar las propiedades y cerrar todas las demás conexiones? si o no
- restaurar su base de datos
- haga los pasos 1-4 cambiando el acceso restringido a MULTI_USER
3ra manera: 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 las bases de datos de SQL Server )
Una restauración solo puede ocurrir si la base de datos no tiene ninguna conexión (además de la suya). La manera más fácil en un servidor MS SQL de expulsar a todos los usuarios es:
ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO
Ahora, puedes realizar tu restauración con impunidad. Asegúrese de volver a establecer el modo multiusuario cuando haya terminado la restauración:
ALTER DATABASE [MyDB] SET Multi_User
GO
solo se puede hacer una conexión a la base de datos. Ejecute el siguiente comando para ver de dónde provienen las conexiones recurrentes a la base de datos.
EXEC SP_WHO2
Verifique esta lista, buscando bajo la columna DBName. Si la base de datos está en la lista, compruebe el ProgramName y la columna HostName para ver quién está intentando conectarse.
Si no se trata de un servicio u otra aplicación que se reconectaría automáticamente y se puede cerrar, anote el número en la columna SPID para cancelar la conexión e inmediatamente comience 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 restablecer la base de datos recién restaurada al modo multiusuario.
ALTER DATABASE DATABASENAME SET MULTI_USER WITH ROLLBACK IMMEDIATE GO
Puede usar el método en el objeto SMO SqlServer para almacenar todos los procesos en una base de datos especificada antes de realizar una restauración:
sqlServer.KillAllProcesses("databaseName");