O instantâneo confirmado de leitura e os níveis de isolamento de instantâneo no SQL Server eliminam a maioria dos bloqueios, exceto um: um gravador ainda bloqueia outros gravadores .
A documentação anda na ponta dos pés dizendo isso e, posteriormente, não documenta mais nada que seria muito interessante saber:
É realmente apenas uma linha modificada que fica bloqueada exclusivamente? Ou também podem ser linhas não relacionadas (por exemplo, adjacentes em um índice) ou páginas?
Eu dei uma olhada nos bloqueios sys.dm_tran_locks
e só vi bloqueios exclusivos em linhas modificadas durante uma transação não confirmada - páginas onde meramente bloqueadas como IX
.
Também testei se duas transações poderiam modificar duas linhas diferentes simultaneamente durante duas transações não confirmadas em uma tabela muito pequena que provavelmente caberia em uma página e que também funcionasse.
Se, de fato, apenas as linhas modificadas forem bloqueadas exclusivamente, isso daria a um aplicativo com acesso exclusivo ao banco de dados a garantia de escrita sem bloqueio se garantir que duas conexões não sejam gravadas simultaneamente na mesma linha.
Isso seria possível no cenário que tenho em mente - mas dificilmente há uma maneira de fazer algo assim se os bloqueios de página entrarem em jogo, pois é imprevisível quais linhas exatamente seriam afetadas.
Regras gerais sobre bloqueios e escalonamento de bloqueios:
Os bloqueios de nível de linha podem ser escalados para bloqueios de nível de tabela (ou nível de partição). Portanto, é possível que linhas não relacionadas sejam bloqueadas, sob determinadas circunstâncias.
Essas circunstâncias estão documentadas aqui . Observe também que o escalonamento de bloqueio pode ser desabilitado com a
LOCK_ESCALATION
opção de tabela.Além disso, alguns planos de consulta usam bloqueios de página, e alguns planos de consulta precisarão ler uma linha bloqueada por outra transação para determinar se ela deve ser modificada. Por exemplo
update foo where someUnindexedColumn = 'someval'
, precisará ler todas as linhas e, portanto, será bloqueado por qualquer outro escritor.Observe isso (que precisaremos no último parágrafo):
Regras sobre
SNAPSHOT
o nível de isolamento :Em suma, neste nível de isolamento:
No entanto, a documentação NÃO menciona que "escritores não bloqueiam escritores", portanto, podemos assumir que os escritores realmente PODEM bloquear escritores no nível de isolamento INSTANTÂNEO.
Mais informações sobre como o instantâneo funciona podem ser encontradas em Bloqueio de transações e Controle de versão de linha :
e abaixo
Este parágrafo acima e especialmente a parte em que os bloqueios são de fato adquiridos pouco antes de os dados serem modificados explicam o comportamento de bloqueio (escritores para escritores) (e considerando a nota "Importante" mencionada no topo):
Então sob
SNAPSHOT
isolamento: