У меня есть консольное пакетное приложение, которое включает в себя процесс, который использует SqlDataAdapter.Fill (DataTable) для выполнения простого SELECT в таблице.Заполнение (DataTable) преуспевает в тестировании, зависает в 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;
}
}
Этот метод выполняется синхронно, и успешно работает в нескольких тестовых средах в течение многих месяцев тестирования - и при запуске из командной строки или запускаются под контролем работы AutoSys.
При переходе в производство процесс зависает - по методу Fill, насколько мы можем это понять. Хуже того, вместо того, чтобы выходить из строя, он, по-видимому, начал порождать новые запросы, а через пару часов потреблял более 5 ГБ памяти на сервере приложений. Это повлияло на другие активные приложения, что сделало меня очень непопулярным. Никакого исключения не было.
Строка соединения примерно такая же ванильная, как и они.
"data source=SERVER\INSTANCE;initial catalog=MyDB;integrated security=True;"
Извинения, если я использую неправильные термины относительно того, что сообщает SQL DBA ниже, но когда мы имели след положить на SQL Server, он показал идентификатор приложения (в соответствии с которым работа AutoSys была запущена) принимаются как действительный логин. Затем сервер обработал запрос SELECT. Однако он никогда не возвращал ответ. Вместо этого он перешел в статус «ожидающей команды». Поток запросов, казалось, оставался открытым в течение нескольких минут, а затем исчез.
Администратор DBA сказал, что не было признаков тупика, но ему нужно было бы контролировать в реальном времени, чтобы определить, есть ли блокировка.
Это происходит только в производственной среде; в тестовых средах серверы SQL всегда отвечали менее чем за секунду.
Идентификатор приложения AutoSys не является новым - он использовался несколько лет с другими SQL-серверами и не имел проблем. Администратор баз данных даже запускал запрос SELECT на рабочем сервере SQL, зарегистрированном в качестве этого идентификатора, и он ответил нормально.
Мы не смогли воспроизвести проблему в любой непроизводственной среде, и не стесняйтесь запускать ее в производстве без административного администратора сервера, чтобы убить процесс. Наши требования безопасности ограничивают мой доступ к просмотру журналов и процессов сервера, и мне обычно приходится привлекать другого специалиста, чтобы посмотреть на них для меня.
Нам нужно решить эту проблему рано или поздно. Объем данных, на которые мы смотрим, в настоящее время составляет всего несколько строк, но будет увеличиваться в течение следующих нескольких месяцев. Из того, что происходит, я полагаю, что это связано с коммуникацией и/или безопасностью между сервером приложений и SQL-сервером.
Любые дополнительные идеи или предметы для расследования приветствуются. Всем спасибо.
С большими базами данных может потребоваться много времени для завершения запроса в VS. Предотвращайте зависание. Я использую BackGroundWorker для выполнения работы. Вместо прямого запроса к базе данных я использую cmd.exe, который является исполняемым файлом командной строки (поставляется с SQL Server) для выполнения запроса и создания файла csv с результатами. Затем читайте результаты в приложении VS. Я запускаю cmd.exe из C#, используя класс процесса изнутри backgbroundworker. – jdweng
@jdweng: Я думаю, что это хорошие моменты. если это один простой оператор select, запустите его из инструмента командной строки sql, исключайте возможность, что что-то не так внутри приложения. Насколько велика таблица? Вы можете запустить select с помощью TOP 1000, чтобы убедиться, что данные результата соответствуют ожиданиям. Запись данных в csv сначала звучит странно для меня в первый момент, но с реальными большими данными это может быть способ. –
В моем приложении sqlcmd.exe занимал 30 минут или больше в базе данных 10 ГБ. Это было часами в качестве запроса в C#. И мои окна для приложения зависли во время выполнения запроса. Единственный метод, который я нашел для получения результатов sqlcmd.exe в C#, был с файлом csv. – jdweng