Как обнаружить тайм-аут SQL Server из приложения .NET без использования исключения Catch
-
01-10-2019 - |
Вопрос
В моем текущем приложении я выполняю обновление, вызывающую команду T-SQL обновления. Проблема в том, что одна и та же запись заблокирована другими пользователями в то время.
При приложении .NE приложение будет ждать, пока SQL Server Timeout он будет бросать тайм-аут SQLException.
Можно ли первым проверить проверку, будь то конкретная запись заблокирована другим процессом, а не ловить исключение?
Решение
Нет, не совсем.
Стандартный способ использовать try/catch
и ручка SqlException
Количество 1205
(пострадавший от тупика) и повторите попытку вашего запроса:
try
{
// do stuff...
}
catch (SqlException sqlEx)
{
switch (sqlEx.Number)
{
case -2: // Client Timeout
case 701: // Out of Memory
case 1204: // Lock Issue
case 1205: // >>> Deadlock Victim
// handle deadlock
break;
case 1222: // Lock Request Timeout
case 2627: // Primary Key Violation
case 8645: // Timeout waiting for memory resource
case 8651: // Low memory condition
...
}
}
ПРИМЕЧАНИЕ: операторы разрыва не добавляются для компактности
Также примечание, Многие проблемы блокировки могут быть устранены путем предоставления соответствующих индексов покрытия.
Другие советы
Вы можете использовать отдельное соединение с очень коротким тайм-аутом, чтобы попытаться заблокировать запись, обновляя некоторое поле, но это все еще не собирается дать вам 100% надежность.
Если у вас действительно есть ситуация с несколькими пользователями редактирования одинаковых записей, вы должны изучить оптимистичные методы блокировки.
Кроме того, убедитесь, что вы не позволяете пользователям блокировать записи вообще - используйте отключенный режим для любых обновлений. Другими словами, блокировка будет происходить только в течение короткого времени обновления (<100 мс)