Если я делаю один вызов к базе данных SQL Server по сети с высокой задержкой, произойдут ли блокировки таблицы из-за этой задержки? Скажем, я запрашиваю таблицу A для некоторых записей, и SQL Server должен возвращать эти данные по медленной сети - будет ли блокировка чтения в таблице A, пока сервер отправляет ответ по сети, или SQL Server снимает блокировку перед отправкой ответ?
Кроме того, будет ли ответ варьироваться в зависимости от размера ответа? Если он просто должен вернуть несколько КБ против нескольких сотен МБ, будет ли это иметь значение?
Создание явной транзакции, выполнение запросов и закрытие транзакции, очевидно, приведет к блокировке таблиц, поскольку длительность транзакции соотносится с моей задержкой.
sql-server
locking
network
Эван М
источник
источник
nolock
подсказку, всегда будет блокировка . Задержка просто определяет, как долго будет удерживаться блокировка.nolock
, что вы все равно получите замкиUnless you specify a nolock hint, there will always be a lock.
<- это означает, что если вы используете nolock, блокировки может не быть. Я просто разъяснял.Ответы:
Это не точно, это зависит от уровня изоляции.
По умолчанию
READ COMMITTED
блокировки не удерживаются на время выполнения операторов.READ COMMITTED
не обеспечивает согласованность чтения на уровне выписки, единственная гарантия состоит в том, что вы не можете прочитать непереданные данные. Общая блокировка получается и удерживается для чтения строки, а затем освобождается.Если у вас нет типов LOB.
Типы больших объектов, потенциально очень большие, не могут быть помещены в буфер. Общая блокировка должна быть получена и удерживаться до завершения инструкции, что по сути дает вам
REPEATABLE READ
поведение вREAD COMMITTED
.Задержка не вызывает блокировку таблицы, нет. Однако, если блокировка таблицы была получена, задержка увеличит ее.
Процитирую кого-то, кто знает механизм этого лучше меня ( @RemusRusanu ):
Там, где результаты потребляются не так быстро, как SQL Server может их доставить, будь то из-за клиента или сети, мы наблюдаем
ASYNC_NETWORK_IO
накопление ожиданий. Повторим, это не повлияет на приобретенные блокировки, а только на продолжительность их удержания.источник
Ответ Марка прояснил мою путаницу, но я хотел опубликовать свои выводы после того, как проверил это с помощью NetBalancer для имитации задержки.
Моя локальная машина вызывала удаленный сервер SQL и выполняла операции SELECT и INSERT для таблицы в рамках небольшой транзакции. На удаленной машине я подключился к локальному экземпляру SQL и использовал цикл WHILE для многократного перебора таблицы sys.dm_tran_locks в поисках любых блокировок в таблице, из которой я изменял и читал. Я установил NetBalancer на сервер и использовал его для эмуляции задержки в сети при сетевом соединении сервера.
Вот что я нашел:
Исходя из этого, я заключаю, что задержка не имеет значения, пока данные помещаются в сетевой буфер. Если SQL должен поместить много данных в сетевой буфер, задержка приведет к резервному копированию этого буфера, и SQL будет удерживать блокировки таблицы до тех пор, пока он не сможет поместить весь результат запроса в буфер.
источник
Когда запрос запускается и завершается SQL Server, он выдает результаты, помещает его в выходной буфер и отправляет его клиенту, который затем извлекает результат из выходного буфера. SQL Server не снимет блокировки, удерживаемые запросом, если от клиента не получено подтверждение. Что может привести к блокировке.
Редактировать: Эван, вы можете обратиться к этой статье поддержки MS
В разделе 3
Блокировка, вызванная SPID, чье соответствующее клиентское приложение не получило все строки результатов для завершения
После отправки запроса на сервер все приложения должны немедленно извлечь все строки результатов до завершения. Если приложение не извлекает все строки результатов, блокировки могут быть оставлены для таблиц, блокируя других пользователей. Если вы используете приложение, которое прозрачно передает операторы SQL на сервер, приложение должно извлечь все строки результатов. Если это не так (и если его нельзя настроить для этого), возможно, вам не удастся решить проблему блокировки. Чтобы избежать проблемы, вы можете ограничить приложения с плохим поведением отчетами или базой данных поддержки принятия решений.
источник
SELECT *
от этого в уREAD COMMITTED
в одном соединении SSMS, монитор блокирует от другого. В любое время, сколько замков вы держали в руках?