Принудительный тайм-аут запроса в SQL Server

79

У нас возникла проблема с блоком кода, который плохо реагирует на медленные базы данных (он ломает кровать при тайм-ауте запроса). Мы создали патч и находимся в процессе регрессии.

Мы не можем получить тайм-аут. Я открыл транзакцию из SQL Mgmt Studio и обновил каждую строку, чтобы заблокировать их, но это не приводит к таймауту INSERT (что мне и нужно).

Могу ли я легко получить блокировку на уровне таблицы через T-SQL? Или мне придется возиться с мастером? Или я могу легко заставить тайм-аут без блокировки? Любой вклад приветствуется.

BnWasteland
источник

Ответы:

131

запустите это, а затем попробуйте вставить ...

select * from yourTable with (holdlock,tablockx)

здесь вы можете заблокировать его на 5 минут:

BEGIN TRANSACTION

SELECT * FROM yourTable WITH (TABLOCKX, HOLDLOCK)

WHERE 0 = 1

WAITFOR DELAY '00:05'

ROLLBACK TRANSACTION
КМ.
источник
Есть ли способ сделать это из C # /. NET, не блокируя поток, который сделал этот вызов SQL Server? Я пытаюсь проверить поведение своего приложения, когда время ожидания соединения истекло. Но если я вызову этот код из C #, я не знаю, как выполнить другой запрос, целенаправленно испытывая тайм-аут.
Джейк Смит,
33

Вы можете просто указать своему sql-коду подождать минуту перед возвратом:

WaitFor Delay '00:01:00'
Дэвид
источник
Проголосовал за простоту ответа. Я проверил это, и он работает
Микель
Я заполнял таблицу и создавал сложные рекурсивные запросы, бафф, чепуха. Они делают свое дело.
DanielV
10

С другой стороны: если соединение настраивается, уменьшите тайм-аут строки подключения до 1 секунды - это упростит задачу. Заполните таблицу кучей данных и пусть 3 других процесса вращаются в цикле, обновляя фрагменты этой таблицы с транзакцией вокруг цикла. Не изменяйте фактическую процедуру, вызываемую приложением (инъекция waitfor). Это делает интеграционный тест недействительным.

Но на самом деле это пример использования модульного тестирования и внедрения зависимостей. Некоторые вещи просто сложно протестировать при интеграции. Модульный тест + внедрение зависимостей .

  • Реальный: код, который гадит -> Тайм-аут базы данных (трудно воспроизвести).
  • Рефакторинг: код, который гадит -> Репозиторий (только доступ к данным) -> База данных
  • Модульный тест: код, который гадит> Мок-репозиторий для выброса -> null
  • Теперь у вас есть неудачный тест на код, который может его исправить.

Это инъекция «зависимости». Разработчик может внедрить зависимость в базу данных, заменив что-то, что имитирует поведение зависимости. Подходит для всех тестов базы данных. В любом случае, имея модульный тест, вы знаете, что исправление делает то, что должно, но вам все равно нужно интеграционное тестирование. В этом случае лучше сосредоточиться на регрессии - это означает, что тестирование ничего не сломало, и функция все еще работает.

Вы уже создали свой патч, поэтому я думаю, что я слишком поздно отвечу.

Осадный
источник