Когда вы выполняете оба утверждения одновременно (SELECT и UPDATE), фактическое поведение будет в основном случайным. Это происходит потому, что ни одна из операций не является мгновенной. Чтобы упростить, рассмотрите таблицу в списке и SELECT перебирает этот список, глядя на одну строку за раз. UPDATE также пытается обновить одну или несколько строк. Когда UPDATE пытается обновить строку позади SELECT, тогда ничего не происходит (без блокировки), потому что SELECT уже прошел мимо точки UPDATE. Если UPDATE пытается обновить строку, в которой SELECT ищет прямо сейчас, то UPDATE придется ждать, пока SELECT будет двигаться, что произойдет очень очень быстро, и UPDATE разблокирует и преуспеет, , а SELECT продвигается вперед. Но если UPDATE обновляет строку вперед из SELECT, то обновление будет успешным и, позже, SELECT в конечном итоге достигнет именно этой строки и остановится, заблокирован.Теперь SELECT должен подождать , пока транзакция, которая сделала UPDATE, не зафиксировала.
Это упрощенная история. Реальная жизнь намного сложнее. SELECT может иметь несколько точек чтения (параллельные планы). И SELECT, и UPDATE подлежат выбору пути доступа, то есть используют один или несколько вторичных индексов для поиска строк. Комплексные запросы могут содержать операторы, которые вызывают множественный поиск в таблице (например, объединения). И SELECT, и UPDATE могут выполнять поиск по закладкам для извлечения данных BLOB, что значительно изменяет поведение блокировки. Оценка мощности может привести к тому, что SELECT будет работать в режиме блокировки с высокой степенью детализации (например, на уровне таблицы Shared lock). UPDATE может инициировать эскалацию блокировки, и эскалация может завершиться неудачей или преуспеть. Choosing different access paths can lead to deadlock. False lock contention can occur due to hash collisions. В этом есть всего несколько переменных. И я даже не упоминал более высокие уровни изоляции (повторяемое чтение, сериализация).
Возможно, вы должны использовать изоляцию SNAPSHOT и перестать беспокоиться об этой проблеме?
Какой уровень изоляции транзакций вы говорите? – Oded
@Oded По умолчанию - я считаю, что он читается. –
* «В настоящее время я не забочусь о грязных данных» *: будьте осторожны [что вы хотите] (http://blogs.msdn.com/b/sqlcat/archive/2007/02/01/previously-committed- строки-может быть пропущенным-если-NOLOCK-подсказка-это-used.aspx). –