Comment obtenir efficace Sql Server blocage de manutention en C# avec ADO?
J'ai une classe "Base de données" qui fonctionne comme un wrapper pour ADO.net. Par exemple, quand j'en ai besoin pour exécuter une procédure, je l'appelle la Base de données.ExecuteProcedure(nom de procédure, parametersAndItsValues).
Nous connaissent de graves problèmes avec les situations de Blocage dans SQL Server 2000. Une partie de notre équipe est de travailler sur le code sql et des opérations afin de minimiser ces événements, mais je pense à faire de cette classe de Base de données solide pour faire face à des situations de blocage.
Nous voulons que la victime du blocage de réessayer peut-être après un certain temps de retard, mais je ne sais pas si c'est possible. Voici le code d'une méthode que nous utilisons:
public int ExecuteQuery(string query)
{
int rows = 0;
try
{
Command.Connection = Connection;
Command.CommandType = CommandType.Text;
if(DatabaseType != enumDatabaseType.ORACLE)
Command.CommandText = query;
else
Command.CommandText ="BEGIN " + query + " END;";
if (DatabaseType != enumDatabaseType.SQLCOMPACT)
Command.CommandTimeout = Connection.ConnectionTimeout;
if (Connection.State == ConnectionState.Closed)
Connection.Open();
rows = Command.ExecuteNonQuery();
}
catch (Exception exp)
{
//Could I add here any code to handle it?
throw new Exception(exp.Message);
}
finally
{
if (Command.Transaction == null)
{
Connection.Close();
_connection.Dispose();
_connection = null;
Command.Dispose();
Command = null;
}
}
return rows;
}
Puis-je faire cette manipulation à l'intérieur d'un bloc catch?
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, je voudrais passer en revue mon SQL 2000 code et entrer jusqu'au fond de pourquoi ce blocage qui se passe. La fixation de ce qui peut se cacher un problème plus grave (par exemple. index manquant ou mauvaise requête).
Deuxième je voudrais passer en revue mon architecture pour confirmer le blocage de déclaration doit vraiment être appelé fréquemment (Ne
select count(*) from bob
être appelé à 100 fois par seconde?).Toutefois, si vous avez vraiment besoin de quelques impasse soutien et n'ont pas d'erreurs dans votre SQL ou de l'architecture d'essayer quelque chose le long des lignes suivantes. (Note: j'ai eu à utiliser cette technique pour un système de soutien des milliers de requêtes par seconde et de frapper des blocages assez rarement)
Thread.Sleep(100);
aprèsretryCount--;
pour éviter de frapper SQL Server si dur.Bâtiment sur @Sam réponse, je vous présente un objectif général de réessayer méthode wrapper:
Si le blocage peut être résolu à la couche de données, c'est certainement le chemin à parcourir. Les indicateurs de verrouillage, avec la refonte de la façon dont le module fonctionne et ainsi de suite. NoLock n'est pas une panacée mais parfois, il n'est pas possible de l'utiliser pour des raisons d'intégrité transactionnelle et j'ai eu des cas de droit (mais complexe) des lectures de données avec toutes les tables NoLock c'est toujours causé des blocs sur les autres requêtes.
De toute façon - si vous ne pouvez pas le résoudre à la couche de données pour quelque raison que ce soit, que diriez -
Si vous obtenez des problèmes de blocages, il serait mieux de regarder ce que le code SQL est en train de faire. Par exemple, lock-escalade blocages sont très faciles à créer si vous avez le niveau d'isolation serializable (ou quelque soit l'équivalent dans votre sgbdr) - et peut être atténué en quelques manières, comme le ré-ordonnancement des requêtes, ou (dans SQL Server au moins) à l'aide de l' (UPDLOCK) de prendre un verrou en écriture antérieure (si vous n'obtenez pas une compétition de lecture-lock).
Re-essayer va être mélangé... par exemple, si vous êtes dans un TransactionScope, il aurait déjà abandonné. Mais juste au puriste niveau - si j'obtiens de problèmes à discuter de la db, je veux que mon code à la panique, et la panique au début... re-essayez semble un peu hacky dans ce scénario particulier.