SQL Server многопоточный оператор SELECT и DELETE - PullRequest
0 голосов
/ 14 марта 2019

У меня довольно большая проблема с одним из наших процессов (я не проектировал его ... кем бы это ни было ...)

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

  1. Чтение данных из клиентской таблицы
  2. Удалить данные из клиентской таблицы

Мне удалось получить INDEX SCAN вместо TABLE SCAN, чтобы он работал довольно быстро (он не станет быстрее). Иногда я получаю DEADLOCK при удалении из-за блокировки SELECT U, которая понятна.

Пока:

  1. Производительность Оптимизирована для сканирования индексов вместо таблицы
  2. ROW_ESCALATION изменено на DISABLED (это очень помогло)

Есть идеи, как избавиться от U-блокировок / тупиков?

Дополнительная информация и журналы

  • Graph Deadlock Graph
  • Журналы - Трассировка по 1204, 1222

05: 14.6 Идентификатор процесса spid20s = process4fe9048 приоритет задачи = 0 logused = 0 waitresource = СТРАНИЦА: 46: 1: 435153 время ожидания = 14827 ownerId = 421628674 транзакция_оператора = 0x73a1e22f2db893448163a72c7caf84b5 транзакция = имя_игранной_стали: транзакция_игры_игры_стата_игры_ транзакции = 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: t = 0: 60t0: 60-й транзистор. = 0x8062f2e0 lockMode = U scheduleID = 12 kpid = 10964 статус = приостановлено spid = 96 sbid = 0 ecid = 1 приоритет = 0 transcount = 0 lastbatchstarted = 2019-03-12T16: 04: 59.790 lastbatchcompleted = 2019-03-12T16: 04: 59.780 clientapp = .Net SqlClient Data Provider имя хоста = SomeHost hostpid = 470604 уровень изоляции = зафиксированное чтение (2) xactid = 421628674 currentdb = 46 lockTimeout = 4294967295 clientoption1 = 673185824 clientoption2 = 128056 05: 14.6 выполнение spid20sStack 05: 14.6 имя_кадра spid20s = SOmeDB.dbo.pr_DeleteCLient line = 14 stmtstart = 296 stmtend = 434 sqlhandle = 0x03002e00c33ec3309ab2b800d1a900000100000000000000 05: 14.6 spid20s УДАЛИТЬ ИЗ dbo.Client 05: 14.6 spid20s ГДЕ InvestorCode = @ InvestorCode
05: 14.6 spid20s inputbuf

  • sys.processes enter image description here

1 Ответ

0 голосов
/ 14 марта 2019

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

Если он выполняется в нескольких сеансах, лучше использовать WITH UPDLOCK или WITH (SERIALIZABLE), как в следующем примере

DECLARE @IdToDelete INT
SELECT @IdToDelete =ID FROM [Your_Table] WITH (SERIALIZABLE) WHERE A=B

DELETE [Your_Table]    
WHERE ID=@IdToDelete 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...