J'ai une application de traitement par lots de la console qui comprend un processus qui utilise pour effectuer un SELECT simple sur une table SqlDataAdapter.Fill (DataTable).Fill (DataTable) réussit à l'essai, dans la production
private DataTable getMyTable(string conStr)
{
DataTable tb = new DataTable();
StringBuilder bSql = new StringBuilder();
bSql.AppendLine("SELECT * FROM MyDB.dbo.MyTable");
bSql.AppendLine("WHERE LEN(IdString) > 0");
try
{
string connStr = ConfigurationManager.ConnectionStrings[conStr].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlDataAdapter adpt = new SqlDataAdapter(bSql.ToString(), conn))
{
adpt.Fill(tb);
}
}
return tb;
}
catch (SqlException sx)
{
throw sx;
}
catch (Exception ex)
{
throw ex;
}
}
Cette méthode est exécutée de façon synchrone, et a été exécuté avec succès dans plusieurs environnements de test sur plusieurs mois de tests - à la fois lors du démarrage de la ligne de commande ou commencé sous le contrôle d'un travail AutoSys.
En cas de déplacement dans la production, cependant, le processus accroché - à la méthode de remplissage autant que nous pouvons dire. Pire, au lieu de temporiser, il a apparemment commencé à engendrer de nouveaux threads de demande, et après quelques heures, avait consommé plus de 5 Go de mémoire sur le serveur d'application. Cela a affecté d'autres applications actives, ce qui m'a rendu très impopulaire. Aucune exception n'a été levée.
La chaîne de connexion est à peu près aussi simple que possible.
"data source=SERVER\INSTANCE;initial catalog=MyDB;integrated security=True;"
Toutes mes excuses si j'utilise les mauvaises conditions en ce qui concerne ce que le DBA SQL indiqué ci-dessous, mais quand nous avions une trace mis sur le serveur SQL, il a montré l'ID d'application (en vertu de laquelle le travail AutoSys était en cours d'exécution) acceptées comme un login valide. Le serveur est ensuite apparu pour traiter la requête SELECT. Cependant, il n'a jamais retourné de réponse. Au lieu de cela, il est entré dans un statut de "commande en attente". Le fil de requête est resté ouvert pendant quelques minutes, puis a disparu.
Le DBA dit qu'il n'y avait aucun signe d'une impasse, mais qu'il aurait besoin de surveiller en temps réel pour déterminer s'il bloquait.
Cela se produit uniquement dans l'environnement de production; Dans les environnements de test, les serveurs SQL répondaient toujours en moins d'une seconde.
Le AutoSys ID d'application n'est pas un nouveau - il a été utilisé depuis plusieurs années avec d'autres serveurs SQL et n'a eu aucun problème. L'administrateur de base de données a même exécuté la requête SELECT manuellement sur le serveur SQL de production connecté en tant que cet ID, et il a répondu normalement.
Nous avons été incapables de reproduire le problème dans un environnement non-production, et hésiter à l'exécuter dans la production sans admin serveur debout pour tuer le processus. Nos exigences de sécurité limitent mon accès pour voir les journaux et les processus du serveur, et je dois généralement engager un autre spécialiste pour les regarder pour moi.
Nous devons résoudre ce problème tôt ou tard. La quantité de données que nous examinons n'est actuellement que de quelques lignes, mais augmentera au cours des prochains mois. De ce qui se passe, ma meilleure estimation est qu'elle implique la communication et/ou la sécurité entre le serveur d'application et le serveur SQL.
Toutes les idées ou éléments supplémentaires à étudier sont les bienvenus. Merci tout le monde.
Avec les bases de données volumineuses, l'exécution de la requête dans VS peut prendre beaucoup de temps. Empêchez la pendaison J'utilise un BackGroundWorker pour faire du travail. Au lieu d'interroger la base de données directement, j'utilise cmd.exe qui est un exécutable en ligne de commande (livré avec SQL Server) pour effectuer une requête et produire un fichier csv avec des résultats. Ensuite, lisez les résultats dans l'application VS. Je lance cmd.exe à partir de C# en utilisant une classe de processus à l'intérieur d'un backgbroundworker. – jdweng
@jdweng: Je pense que ce sont quelques bons points. s'il s'agit d'une simple instruction select, exécutez-la à partir de l'outil de ligne de commande sql, excluez la possibilité que quelque chose ne fonctionne pas dans l'application. Quelle est la taille de la table? Vous pouvez exécuter la sélection avec TOP 1000 pour vous assurer que les données de résultat sont comme prévu. Écrire des données à csv d'abord sembler étrange pour moi le premier moment, mais avec des données vraiment importantes, cela peut être un moyen. –
Avec mon application, sqlcmd.exe prenait 30 minutes ou plus sur une base de données de 10 Go. Il prenait des heures comme une requête en C#. Et mes fenêtres pour l'application ont été suspendues pendant que la requête était en cours d'exécution. La seule méthode que j'ai trouvée pour obtenir les résultats de sqlcmd.exe dans C# était avec un fichier csv. – jdweng