37 votes

L'accès exclusif n'a pas pu être obtenu car la base de données est en cours d'utilisation.

J'utilise le code suivant pour restaurer les bases de données,

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

mais je reçois l'exception suivante

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

Comment puis-je le réparer ?

52voto

KeithS Points 36130

Une restauration ne peut avoir lieu que si la base de données n'a aucune connexion (à part la vôtre). Le moyen le plus simple de mettre tous les utilisateurs hors service est de le faire sur un serveur MS SQL :

ALTER DATABASE [MyDB] SET Single_User WITH Rollback Immediate
GO

Maintenant, vous pouvez effectuer votre restauration en toute impunité. Assurez-vous de le remettre en mode multi-utilisateur lorsque vous avez terminé la restauration :

ALTER DATABASE [MyDB] SET Multi_User
GO

14voto

Mohammad Points 2448

J'ai donc écrit la méthode ci-dessous pour restaurer ma base de données,
Suis-je dans la bonne voie ?

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";
    }
}

9voto

imanabidi Points 3203

La meilleure approche

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 
  • AVEC RETOUR EN ARRIÈRE IMMÉDIAT - cette option n'attend pas pour les transactions pour terminer, il commence juste à annuler toutes les transactions ouvertes.

  • AVEC ROLLBACK APRÈS nnn - cette option annulera toutes les transactions ouvertes transactions ouvertes après avoir attendu nnn secondes pour que les transactions ouvertes soient s'achèvent. Dans notre exemple, nous spécifions que le processus doit 30 secondes avant de revenir en arrière sur les transactions ouvertes.

  • Cuando UTILISATEUR RESTREINT est spécifié, seuls les membres de la db_owner, dbcreator, ou sysadmin peuvent utiliser la base de données. MULTI_USER ramène la base de données à son état de fonctionnement normal.


2ème façon : en utilisant ssms 2008 R2 nous pouvons faire la même chose.

  1. cliquez avec le bouton droit de la souris sur la propriété de la base de données
  2. allez dans les options -> dernière section avec en-tête de état
  3. changement Restreindre l'accès a SINGLE_USER
  4. répondre par l'affirmative à cette question utile qui montre que ce type d'action va fermer toutes les autres connexions et je suppose que c'est la seule chose que nous cherchons ici pour contourner l'erreur.

Pour modifier les propriétés de la base de données, SQL Server doit fermer toutes les autres connexions à la base de données. Êtes-vous sûr de vouloir modifier les propriétés et fermer toutes les autres connexions ? oui ou non

  1. restaurer votre base de données
  2. faire les étapes 1-4 en changeant Restreindre l'accès retour à MULTI_USER

3ème voie : les commandes suivantes fermeront également toutes les connexions.

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

maintenant la base de données est prête à être restaurée

Plus ( mssqltips :Obtenir un accès exclusif pour restaurer des bases de données SQL Server )

9voto

Martin Bell Points 11

Vous pouvez utiliser la méthode sur l'objet SMO SqlServer pour tuer tous les processus sur une base de données spécifiée avant d'effectuer une restauration :

sqlServer.KillAllProcesses("databaseName");

1voto

Dave Points 3005

La raison de ce problème est évidente (connexions à la base de données actuellement ouvertes/actives), mais utilisez ce qui suit (googlez-le aussi pour le comprendre) et tout ira bien :

Alter Database YOURDB   
SET SINGLE_USER With ROLLBACK IMMEDIATE
GO

De toute évidence, il faut remplacer YOURDDB avec le nom de votre base de données et exécutez-la contre la base de données principale.

Oh, et juste au cas où, si vous êtes "coincé" en mode utilisateur unique, ceci le défait :

Alter Database YOURDB   
SET MULTI_USER With ROLLBACK IMMEDIATE
GO

J'espère que cela vous aidera.

EDITAR:

Vous pouvez également suivre ce pour voir d'où viennent les connexions et d'autres informations :

J'ai testé cela tout en ayant des services qui se reconnectaient à la base de données base de données. J'ai découvert que vous deviez passer en mode utilisateur unique, puis lancer sp_who2 pour voir d'où venait la connexion unique d'où provenait la connexion et noter le SPID. Vous pouvez lancer la commande kill pour ce SPID et la restauration dans la même même transaction, et ça devrait marcher. Voici la séquence que j'ai utilisée :

UTILISER MASTER ALTER BASE DE DONNÉES NOM_DE_DONNÉES DÉFINIR SINGLE_USER AVEC ROLLBACK IMMÉDIATEMENT

-Cela fera en sorte qu'une seule connexion à la base de données puisse être base de données. -Lancez la commande suivante pour voir d'où proviennent les connexions récurrentes à la base de données proviennent.

EXEC SP_WHO2

-Vérifiez cette liste, en regardant sous la colonne DBName. Si la base de données est base de données, vérifiez les colonnes ProgramName et nom d'hôte pour voir qui qui tente de se connecter. S'il ne s'agit pas d'un service ou d'une autre application qui se reconnecte automatiquement et qui peut être arrêtée, notez-le. automatiquement et qui peut être arrêtée, notez le numéro dans la colonne SPID pour couper la la connexion, et commencer immédiatement la sauvegarde. Remplacez SPID ci-dessous par seulement le numéro.

KILL SPID RESTORE DATABASE NOM DE LA BASE DE DONNÉES À PARTIR DU DISQUE = ' X:\PATHTO\BACKUP.BAK GO

-Si cela se termine avec succès, nous pouvons remettre la base de données nouvellement restaurée en mode multi-utilisateur.

ALTERNER LA BASE DE DONNÉES NOM DE LA BASE DE DONNÉES MULTI_USER AVEC ROLLBACK IMMÉDIAT GO

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X