Минимизировать взаимоблокировки с намеренно изобретенными + высококонкурентными транзакциями? - PullRequest
1 голос
/ 25 марта 2011

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

В настоящее время у меня есть два типа транзакций (для демонстрации грязного чтения, но это не имеет значения):

Тип транзакции A: Выбратьвсе строки из таблицы A.

Тип транзакции B: Установите значение 'cost' = 0 во всех строках таблицы A, затем немедленно выполните откат.

В настоящее время я запускаю пул потоков из 1000 потоков и 10000транзакции, где каждый поток произвольно выбирает между выполнением типа транзакции A и типа транзакции B. Однако я получаю тонну взаимоблокировок даже при принудительной блокировке строки.

Я предполагаю, что взаимные блокировки возникают из-за строкиупорядочение получаемых блокировок, то есть, если и таблица типа А, и таблица «сканирования» типа А в одном и том же порядке, например сверху вниз, такие взаимные блокировки не могут возникнуть.Однако у меня возникают проблемы с выяснением того, как заставить SQL Server поддерживать порядок строк во время операторов SELECT и UPDATE.

Есть советы?Первый раз в стеке потока, поэтому, пожалуйста, будьте осторожны: -)

РЕДАКТИРОВАТЬ: уровень изоляции преднамеренно установлен на READ_COMMITTED, чтобы показать, что он устраняет грязные чтения (и это делает).Взаимные блокировки возникают только на любом уровне, равном или превышающем READ_COMMITTED;очевидно, что в READ_UNCOMMITTED не возникает взаимоблокировок.

РЕДАКТИРОВАТЬ 2: Эти транзакции выполняются на новом экземпляре AdventureWorks LT на SQL Server 2008R2.

1 Ответ

1 голос
/ 28 марта 2011

Если вы запускаете транзакцию для обновления всех строк, введите B, а затем откатываете транзакцию, необходимо будет удерживать блокировку для всей этой транзакции во всех строках.Даже если у вас есть блокировки на уровне строк, блокировку необходимо удерживать для всей транзакции.

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

Когда вы разрабатываете систему с высокой степенью параллелизма, вам следует избегать запросов, которые блокируют всю таблицу.Я рекомендую следующее руководство MicroSoft для понимания блокировок и уменьшения их воздействия:

http://technet.microsoft.com/en-us/library/cc966413.aspx

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