Блокировка транзакций SQL (b) - правильно ли я понимаю - PullRequest
2 голосов
/ 06 апреля 2009

Мы используем ADO.NET для подключения к серверу SQL 2005, и делаем несколько вставок / обновлений и выбираем на нем. Мы изменили одно из обновлений так, чтобы оно было внутри транзакции, однако, по-видимому, оно (b) блокирует всю таблицу, когда мы делаем это, независимо от IsolationLevel, который мы установили для транзакции.

Я, похоже, вижу поведение:

  1. Если у вас нет транзакций, тогда это полный бой (проигравшие становятся заблокированными)
  2. Если у вас есть несколько транзакций, они все время выигрывают и блокируют все остальные, если только
  3. Если у вас есть несколько транзакций, и вы устанавливаете что-то вроде nolock на остальные, то вы получаете транзакции и ничего не блокируется. Это потому, что каждый оператор (выбрать / вставить / удалить / обновить) имеет уровень изоляции независимо от транзакций .

Это правильно?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2009

Ответ на ваш вопрос: это зависит.

Если вы обновляете таблицу, SQL Server использует несколько стратегий, чтобы решить, сколько строк заблокировать, блокировки на уровне строк, блокировки страниц или полные блокировки таблиц.

Если вы обновляете более определенного процента таблицы (настраивается, насколько я помню), тогда SQL Server предоставляет вам блокировку на уровне таблицы, которая может блокировать выбор.

Лучшая ссылка:

Удачи.

1 голос
/ 06 апреля 2009

Ваш оператор обновления (т. Е. Тот, который изменяет данные) будет удерживать блокировки независимо от уровня изоляции и от того, явно ли вы определили транзакцию, которой нет.

То, что вы можете контролировать, - это гранулярность блокировок, используя подсказки запроса . Поэтому, если обновление блокирует всю таблицу, вы можете указать подсказку запроса, чтобы заблокировать только затронутые строки (подсказка ROWLOCK). Это если, конечно, ваш запрос не обновляет всю таблицу.

Таким образом, чтобы ответить на ваш вопрос, первое соединение с запросом блокировок на ресурсе будет удерживать эти блокировки на время транзакции. Вы можете указать, что выборка не удерживает блокировки, используя уровень изоляции «незафиксированное чтение», операторы, которые изменяют вставку / обновление / удаление данных, всегда сохраняют блокировки независимо. Следующее соединение для запроса блокировок на том же ресурсе будет ожидать завершения первого, а затем будет удерживать свои блокировки. Мертвая блокировка - это особый сценарий, когда два соединения удерживают блокировки, и каждое из них ожидает ресурс другого соединения, чтобы избежать вечного ожидания механизма, одно соединение выбрано в качестве жертвы тупика.

...