Se eu estiver fazendo uma única chamada para um banco de dados do SQL Server em uma rede de alta latência, os bloqueios de tabela ocorrerão devido a essa latência? Digamos que eu consulte a tabela A para alguns registros e o SQL Server precise retornar esses dados em uma rede lenta - haverá um bloqueio de leitura na tabela A enquanto o servidor envia a resposta pela rede ou o SQL Server libera o bloqueio antes de enviar a resposta?
Além disso, a resposta varia com base no tamanho da resposta? Se ele apenas devolver algumas KB vs várias centenas de MB, isso faria alguma diferença?
Criar uma transação explícita, executar consultas e fechar a transação obviamente causaria o bloqueio das tabelas, pois a duração da transação está correlacionada com a minha latência.
fonte
nolock
dica, sempre haverá um bloqueio . A latência apenas determina quanto tempo o bloqueio será mantido.nolock
, você ainda terá bloqueiosUnless you specify a nolock hint, there will always be a lock.
<- isso implica que, se você usar o nolock, talvez não haja bloqueios. Eu estava apenas esclarecendo.Respostas:
Isso não é exato, depende do nível de isolamento.
Nos
READ COMMITTED
bloqueios padrão, não são mantidos durante a execução das instruções.READ COMMITTED
não fornece consistência de leitura no nível da instrução, a única garantia é que você não pode ler dados não confirmados. Um bloqueio compartilhado é adquirido e mantido para ler a linha e, em seguida, liberado.A menos que você tenha tipos de LOB.
Os tipos de LOB, sendo potencialmente muito grandes, não podem ser armazenados em buffer. Um bloqueio compartilhado deve ser adquirido e mantido até que a instrução seja concluída, fornecendo essencialmente um
REPEATABLE READ
comportamento emREAD COMMITTED
.A latência não está causando o bloqueio da tabela, não. No entanto, se um bloqueio de tabela foi adquirido, a latência vai prolongá-lo.
Para citar alguém que conhece a mecânica disso melhor do que eu ( @RemusRusanu ):
Onde os resultados não são consumidos tão rapidamente quanto o SQL Server pode entregá-los, seja devido ao cliente ou à rede, vemos as
ASYNC_NETWORK_IO
esperas se acumulando. Para reiterar, isso não influenciará os bloqueios adquiridos, apenas a duração em que eles são mantidos.fonte
A resposta de Mark esclareceu muita confusão, mas eu queria postar minhas descobertas depois de testar isso usando o NetBalancer para emular a latência.
Minha máquina local chamou um servidor SQL remoto e executou SELECTs e INSERTs em uma tabela dentro de uma pequena transação. Na máquina remota, conectei-me à instância SQL local e usei um loop WHILE para iterar repetidamente sobre a tabela sys.dm_tran_locks, procurando por bloqueios na tabela que eu estava modificando e lendo. Instalei o NetBalancer no servidor e o usei para emular a latência da rede na conexão de rede do servidor.
Aqui está o que eu encontrei:
A partir disso, concluo que a latência não importa, desde que os dados caibam no buffer da rede. Se o SQL precisar colocar muitos dados no buffer de rede, a latência fará o backup desse buffer e o SQL manterá os bloqueios da tabela até que ele possa colocar todo o resultado da consulta no buffer.
fonte
Quando uma consulta é disparada e concluída pelo SQL Server, ela produz os resultados, coloca-a no buffer de saída e envia-a ao cliente, que busca o resultado no buffer de Saída. O SQL Server não liberará os bloqueios mantidos pela consulta, a menos que seja recebida uma confirmação do cliente. O que pode causar o bloqueio.
Edit: Evan, você pode consultar este artigo de suporte da MS
Na seção 3
Bloqueio causado por um SPID cujo aplicativo cliente correspondente não obteve todas as linhas de resultado até a conclusão
Depois de enviar uma consulta ao servidor, todos os aplicativos devem buscar imediatamente todas as linhas de resultados até a conclusão. Se um aplicativo não buscar todas as linhas de resultado, os bloqueios poderão ser deixados nas tabelas, bloqueando outros usuários. Se você estiver usando um aplicativo que envie transparentemente instruções SQL para o servidor, o aplicativo deverá buscar todas as linhas de resultados. Caso contrário (e se não puder ser configurado para isso), talvez você não consiga resolver o problema de bloqueio. Para evitar o problema, você pode restringir aplicativos mal comportados a um banco de dados de relatórios ou de suporte à decisão.
fonte
SELECT *
dele emREAD COMMITTED
uma conexão SSMS, o monitor bloqueia a partir de outra. A qualquer momento, quantos bloqueios você vê retidos?