Question

J'ai des problèmes avec SQL Server lors de la suppression d'une connexion après avoir supprimé et recréé une base de données donnée. La prochaine fois que j'essaie d'exécuter une commande sur une nouvelle connexion sur cette même base de données, je reçois:

  

Une erreur de niveau de transport s'est produite lors de l'envoi de la demande au serveur. (fournisseur: fournisseur de mémoire partagée, erreur: 0 - aucun processus n’est à l’autre extrémité du canal.)

Voici la version TCP (si je tente de me connecter à un autre serveur)

  

Une erreur de niveau de transport s'est produite lors de l'envoi de la demande au serveur. (fournisseur: fournisseur TCP, erreur: 0 - une connexion existante a été fermée de force par l'hôte distant.)

Voici les étapes à suivre pour reproduire le problème:

  1. Ouvrez une connexion à une base de données et exécutez une commande sql
  2. Supprimer la base de données
  3. Recréez la base de données
  4. Ouvrez une nouvelle connexion à la même base de données et essayez d’exécuter une commande à ce sujet

Résultat: je reçois une exception

Voici le code:

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=DBNAME;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

string sql = "Alter Database DBNAME set single_user with rollback immediate drop database DBNAME";
var server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

sql = File.ReadAllText("PathToDotSqlFile..."));
server = new Microsoft.SqlServer.Management.Smo.Server(".");
server.ConnectionContext.ExecuteNonQuery(sql);
server.ConnectionContext.Disconnect();

using (var conn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=WER_CONFIG;Integrated Security=True"))
{
    conn.Open();
    var cmd = conn.CreateCommand();
    cmd.CommandText = "UPDATE ...";
    cmd.ExecuteNonQuery();
}

L'erreur se produit sur la ligne 'cmd.ExecuteNonQuery ()' à la toute fin. Il semble que même si je crée une nouvelle connexion chaque fois que je me connecte, SQL Server garde une trace de quelque chose (ou éventuellement du code ADO.net) où la prochaine fois que je demanderai une connexion, cela me donnera une connexion déjà utilisée ou a été fermé côté serveur. Il ne réalise pas qu'il a été fermé par le serveur (probablement à cause de la base de données à laquelle il est connecté), jusqu'à ce que vous essayiez d'exécuter une autre commande.

Notez que si je ne fais pas la première étape de l'exécution de la requête initiale et que je supprime simplement la base de données, la recrée, et exécute une commande, je ne reçois pas cette erreur. Je pense que l’établissement de cette connexion initiale avant que la base de données ne soit abandonnée est une partie importante de cette erreur.

J'ai également essayé d'utiliser un processus externe pour supprimer et recréer la base de données comme suit:

ProcessStartInfo info = new ProcessStartInfo("sqlcmd.exe", " -e -E -S . -Q \"Alter Database DBNAME set single_user with rollback immediate drop database DBNAME\"");
var p = Process.Start(info);
p.WaitForExit();

info = new ProcessStartInfo("sqlcmd.exe", " -i " + PathToDotSqlFile);
p = Process.Start(info);
p.WaitForExit();

Et cela n'a pas aidé.

Existe-t-il un moyen de créer un nouveau SqlConnection et de s’assurer qu’il est propre et ne provient pas d’un pool? D'autres suggestions sur la façon de résoudre ce problème?

UPDATE: L’utilisation de SqlConnection.ClearPool () a résolu le problème, mais j’ai choisi de modifier ma chaîne de connexion avec pooling = false, ce qui a également fonctionné.

Était-ce utile?

La solution

ADO.NET gère automatiquement un pool de connexions. Lorsque vous fermez " une connexion dans votre application, elle est renvoyée dans le pool et maintenue active au cas où vous demanderiez une connexion avec la même chaîne de connexion. Cela pourrait être la raison pour laquelle votre " nouveau " la connexion est périmée.

Vous pouvez essayer de désactiver ce comportement en ajoutant pooling = false en tant que paramètre à votre chaîne de connexion.

Autres conseils

Je ne connais pas SQL2008, mais cela ressemble à un problème de regroupement de connexions du côté de l'application. Auparavant, nous ajoutions "Services OLEDB = -1". à la chaîne de connexion pour désactiver le regroupement de connexions. Il existe probablement un moyen plus élégant de le faire maintenant.

edit: ADO.Net 2.0 semble avoir ajouté une fonction ClearPool à l'objet SQLConnection. ( http: // msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool(VS.80).aspx ) Je suis très intéressé de savoir si cela fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top