Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Sql server первое обновление очень долгое

Доброго времени суток! Имеется код на C#:
try { using (var ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 2, 0, 0))) { using (var sqlConnection1 = new SqlConnection(Settings.Default.DefaultConnectionString)) { var taDivisions = new DivisionsTableAdapter();
try { sqlConnection1.Open();
taDivisions.Update(data);
ts.Complete(); } finally { if (sqlConnection1.State != ConnectionState.Closed) sqlConnection1.Close(); } } } } catch (Exception exception) { //Log it throw; }
Проблема в следующем: при первом выполнении, затраченное время ~ 1 минута ( иногда больше ), притом что в таблице не более 10 строк, и за раз изменяется не более чем 1 строка. Причем время выполнения не зависит вообще никак от таблицы которую обновляем. Запрос выполняется, не отваливается по таймауту, при следующем выполнении - обновление происходит моментально. Конфигурация: 2 сервака IIS + SQL Server Читал что сиквел сервер при обращение кэширует запросы, поэтому при первом обновлении такое происходит. Буду признателен если дадут комментарий, либо реальную причину по которой это может происходить, либо на что обратить внимание. Спасибо!
UPD.

Скрин как раз сделан в момент обновления, который занял ~ 1.5 минуты на 1 запись
UPD. UPD.
Проблема явно в использовании транзакций. Если этот же самый код использовать без транзакции все работает очень хорошо. Если применить: проблема та же, первый раз очень долго выполняется.


Ответ

Если присмотреться к вашему коду, то в нем есть подвох - вы нигде не используете sqlConnection1. Т.е. вы его создаете, открываете и сразу закрываете. В DivisionsTableAdapter вы его не передаете.
Вызов taDivisions.Update(data); использует какое-то другое соединение. А sqlConnection1 в коде никак не используется. Но мешает.
По сути вы открываете два соединения в рамках одного Transaction Scope. Это приводит к регистрации транзакции как распределенной, через механизм MS Distributed Transaction Coordinator.
Этот механизм требует настройки Firewall. Кроме того, он требует огромных накладных расходов по сравнению с обычными транзакциями.
Уберите из кода работу с sqlConnection1 - и он заработает быстро:
using (var ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 2, 0, 0))) { var taDivisions = new DivisionsTableAdapter(); taDivisions.Update(data); ts.Complete(); }
А еще лучше - перестаньте работать через TableAdapter-ы и DataSet-ы - это древний механизм для работы с данными, он не дает ни типизации, ни нормального контроля над выполняемым кодом. Возьмите или Entity Framework (строгая типизация) или Dapper (контроль и скорость).

Комментариев нет:

Отправить комментарий