Как получить эффективную обработку мертвой блокировки SQL-сервера в C# с ADO?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
21
задан redcalx 1 April 2011 в 09:56
поделиться

3 ответа

Во-первых, я рассмотрел бы свой SQL, который 2000 кодирует и добирается до сути относительно того, почему эта мертвая блокировка происходит. Фиксация этого может скрывать большую проблему (Например, пропускать индекс или плохой запрос).

113-секундный я рассмотрел бы свою архитектуру, чтобы подтвердить, что заходящий в тупик оператор действительно нужно назвать, это часто (select count(*) from bob должен быть назван 100 раз в секунду?).

Однако, если Вы действительно нуждаетесь в некоторой поддержке мертвой блокировки и не имеете никаких ошибок в Вашем SQL или архитектуре, пробуют что-то вдоль следующих строк. (Отметьте: Я должен был использовать эту технику для системы, поддерживающей тысячи запросов в секунду, и поражал бы мертвые блокировки вполне редко)

int retryCount = 3;
bool success = false;  
while (retryCount > 0 && !success) 
{
  try
  {
     // your sql here
     success = true; 
  } 
  catch (SqlException exception)
  {
     if (exception.Number != 1205)
     {
       // a sql exception that is not a deadlock 
       throw; 
     }
     // Add delay here if you wish. 
     retryCount--; 
     if (retryCount == 0) throw;
  }
}
36
ответ дан 29 November 2019 в 06:31
поделиться

Если мертвая блокировка может быть решена на слое данных, это - определенно способ пойти. При блокировке подсказок перепроектировании пути модуль работает и так далее. NoLock не является панацеей, хотя - иногда не возможно использовать по причинам целостности транзакций, и у меня были случаи прямых (хотя сложный), данные читают со всеми соответствующими таблицами NoLock'd, который все еще вызвал блоки на других запросах.

Так или иначе - если Вы не можете решить его на слое данных по любой причине, как насчет

bool OK = false;
Random Rnd = new Random();

while(!OK)
{
    try
    {
        rows = Command.ExecuteNonQuery();
        OK = true;
    }
    catch(Exception exDead)
    {
        if(exDead.Message.ToLower().Contains("deadlock"))
            System.Threading.Thread.Sleep(Rnd.Next(1000, 5000));
        else
            throw exDead;
    }
}
5
ответ дан 29 November 2019 в 06:31
поделиться

Если бы Вы получаете проблемы с мертвыми блокировками, было бы лучше посмотреть на то, что делает код SQL. Например, мертвые блокировки повышения уровня блокировок очень легко создать, если у Вас есть уровень сериализуемой изоляции (или независимо от того, что эквивалент находится в Вашем rdbms) - и может быть смягчен несколькими способами, такими как переупорядочение запросов, или (в SQL Server, по крайней мере) использование (UPDLOCK) для взятия блокировки записи ранее (таким образом, Вы не получаете конкурирующую блокировку чтения).

Повторение будет смешанным..., например, если Вы находитесь в TransactionScope, оно, возможно, уже прервалось. Но только на пуристском уровне - если я получаю проблемы, говорящие с дб, я хочу, чтобы мой код запаниковал, и запаниковал, рано... повторная попытка кажется небольшим hacky в этом конкретном сценарии.

3
ответ дан 29 November 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: