Тупик при обновлении таблицы SQL Server 2008 через многозадачность - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть таблица в SQL Server с этой схемой:

RunJob Table 
(
    id identity,
    SqlCode nvarchar(max)   -- store dynamic sql which will be executed by SP.
    Start_time              -- will be null at the start,  will be updated at the start of SqlCode column's dynamic sql execution
    EndTime                 -- end time of SqlCode dynamic sql execution 
    Status char(2)          -- initially it will be NS(no started), IP (in progress while execution of SqlCode) , CO or FA ( completed or failed at the end)
)

Таблица содержит около 25000 строк.Я использую многозадачную программу C # для вызова одной хранимой процедуры SQL Server из 4 потоков.

Таким образом, одна и та же хранимая процедура будет вызываться 4 раза одновременно.Эта хранимая процедура имеет цикл while и выбирает максимальный идентификатор, где Startime равен нулю, а статус равен NS (не запущен).

Для этой строки хранимая процедура установит начальную дату, staus в IP, получит текстиз столбца SqlCode и выполните его, и в конце он обновит значения Endtime и status до Co\FA.

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

Но я все еще получаю взаимоблокировки при обновлении моей таблицы RunJob.

Может кто-нибудь предложить, что еще я могу сделать, чтобы избежать взаимоблокировок?

Еще один момент - после использования уровня транзакции, считанного незафиксированным, я получаю меньше взаимоблокировок.^

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Если вы хотите равномерно распределить рабочую нагрузку на эти 4 потока.Затем вы можете использовать NTILE (4) over (cols), чтобы получить номера потоков.

Таким образом, можно избежать цикла WHILE, который выполняет логику MAX (id), если это является причиной возникновения взаимоблокировок.

Было бы лучше понять, что происходит вхранимая процедура, чтобы предложить другие альтернативы

0 голосов
/ 01 февраля 2019

По моему опыту, при работе с параллельными сценариями, которые вы описываете, вам, вероятно, лучше всего использовать sp_getapplock (за которым следует sp_releaseapplock) на очень детальном уровне.Энди Новик очень хорошо объясняет это в этой статье: https://www.mssqltips.com/sqlservertip/3202/prevent-multiple-users-from-running-the-same-sql-server-stored-procedure-at-the-same-time/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...