Случайный тупик - PullRequest
       9

Случайный тупик

2 голосов
/ 01 декабря 2008

У меня проблемы с веб-приложением, которое иногда блокируется

3 запроса. 2 пытаются обновить таблицу

UPDATE AttendanceRoll
SET ErrorFlag = 0
WHERE ContractID = @ContractID
AND DATEPART(month,AttendanceDate) = DATEPART(month,@Month_Beginning)
AND DATEPART(year,AttendanceDate) = DATEPART(year,@Month_Beginning)

и один пытается вставить в таблицу

INSERT INTO AttendanceRoll 
    (AttendanceDate, ContractID, PersonID, 
    StartTime, 
    EndTime, 
    Hours, AbsenceReason,
    UpdateCount, SplitShiftID, ModifiedBy, ModifiedDate)
SELECT   
    @P33,  @P34,  @P35,
    CONVERT(datetime,REPLACE( @P36, '.', ':')),
    CONVERT(datetime,REPLACE( @P37, '.', ':')),
    @P38,  @P39,  
    @P40, 1,  @P41, GETDATE()

График взаимоблокировки показывает своего рода циклическое расположение блокировок страниц и события обмена, и два запроса на обновление имеют одинаковый идентификатор процесса сервера.

Если у кого-нибудь есть идеи о том, как мне следует решить эту проблему, это было бы очень ценно.

У меня есть график взаимоблокировки, который я могу опубликовать, если кому-то нужно его увидеть.

Спасибо Карл Р

Ответы [ 5 ]

1 голос
/ 01 декабря 2008

я бы предположил, что ваши обновления выполняют сканирование таблиц и в конечном итоге увеличивают блокировку строк в блокировку страниц в блокировку таблиц, что предотвращает завершение вставки

я думаю, что есть настройка, которая запрещает выход за пределы блокировки строк, вы можете попробовать это в первую очередь

в противном случае вам, возможно, придется выделить и проиндексировать данные месяца, чтобы сделать обновления более эффективными

1 голос
/ 01 декабря 2008

- После предложений Жоргебургоса, затем ...

Если это тупик, то при условии, что есть только 2 участника, один должен быть жертвой, а другой будет завершен.

Вы можете встроить обнаружение взаимоблокировок в слой данных и сделать так, чтобы повторные операции завершались неудачно для взаимоблокировок.

Используйте разные механизмы блокировки табличных подсказок, чтобы минимизировать диапазон оспариваемых ресурсов. Я не знаю, какие применяются к версии SQL, которую вы используете, но здесь из MSDN. http://msdn.microsoft.com/en-us/library/ms187373.aspx

1 голос
/ 01 декабря 2008

Не глядя на графики взаимоблокировок и связанные с ними рабочие нагрузки, а также на основе того, что вы говорите о существовании обмена, вы, вероятно, зашли в тупик с параллелизмом. http://msdn.microsoft.com/en-us/library/aa937571(SQL.80).aspx. Ваш график взаимоблокировки похож на тот, что был в предыдущей статье?

Можете ли вы отключить parralesim для запроса? Существует подсказка OPTION (MAXDOP 1), которая отключит его для определенного запроса. Включите это и посмотрите, поможет ли это. http://msdn.microsoft.com/en-us/library/ms181714.aspx

Оптимизация индексов также может помочь устранить тупик, устраняя необходимость в параллесиме.

1 голос
/ 01 декабря 2008

Требуется ли для выполнения запроса на обновление значительное время (скажем, более секунды)? Если это так, попробуйте оптимизировать запрос (например, поместив индексы в сокращенный столбец и т. Д.)

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

0 голосов
/ 16 апреля 2010

Я обычно заключаю все свои вызовы на SQL-сервер внутри чего-то вроде (в точности это не скомпилируется, но вы поймете):

for (;;) {
    try {
        using (var t = BeginTransaction()) {
            DoTheCall();
            t.Commit();
            return;
        }
    }
    catch (SqlException ex) {
        if (ex.Number != 1205 && ex.Number != 601 && ex.Number != 605)
            throw;
    }
}
...