Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Alterações de nível de isolamento do SQL Server padrão


Em seu cenário, eu recomendaria definir explicitamente o nível de isolamento para instantâneo - isso impedirá que a leitura atrapalhe as gravações (inserções e atualizações), evitando bloqueios, mas essas leituras ainda seriam "boas" leituras (ou seja, dados não sujos - não é o mesmo que um NOLOCK)

Geralmente eu acho que onde eu tenho problemas de bloqueio com minhas consultas, eu controlo manualmente o bloqueio aplicado. por exemplo. eu faria atualizações com bloqueios em nível de linha para evitar bloqueio em nível de página/tabela e definiria minhas leituras como readpast (aceitando que posso perder alguns dados, em alguns cenários que podem ser ok) link|edit|delete|flag

EDIT - Combinando todos os comentários na resposta

Como parte do processo de otimização, o sql server evita leituras confirmadas em uma página que ele sabe que não foi alterada e retorna automaticamente para uma estratégia de bloqueio menor. No seu caso, o sql server cai de uma leitura serializável para uma leitura repetível.

P:Obrigado por essas informações úteis sobre a queda dos níveis de isolamento. Você consegue pensar em algum motivo para usar o Serializable IsolationLevel em primeiro lugar, já que não usamos uma transação explícita para o SELECT - era nosso entendimento que a transação implícita usaria ReadCommitted?

R:Por padrão, o SQL Server usará Read Commmited se esse for seu nível de isolamento padrão, MAS se você não especificar adicionalmente uma estratégia de bloqueio em sua consulta, estará basicamente dizendo ao sql server "faça o que achar melhor, mas minha preferência é Leitura confirmada". Como o SQL Server é livre para escolher, o faz para otimizar a consulta. (O algoritmo de otimização no sql server é muito complexo e eu mesmo não o entendo completamente). Não executar explicitamente em uma transação não afeta o nível de isolamento que o sql server usa.

P:Uma última coisa, parece razoável que o SQL Server aumente o nível de isolamento (e presumivelmente o número de bloqueios necessários) para otimizar a consulta? Também estou querendo saber se a reutilização de uma conexão em pool afetaria isso se ela herdasse o último nível de isolamento usado?

R:O Sql Server fará isso como parte de um processo chamado "Lock Escalation". De http://support.microsoft.com/kb/323630 , cito:"O Microsoft SQL Server determina dinamicamente quando executar o escalonamento de bloqueios. Ao tomar essa decisão, o SQL Server leva em consideração o número de bloqueios mantidos em uma verificação específica, o número de bloqueios mantidos por toda a transação, e a memória que está sendo usada para bloqueios no sistema como um todo. Normalmente, o comportamento padrão do SQL Server resulta em escalonamento de bloqueio ocorrendo apenas nos pontos em que melhoraria o desempenho ou quando você deve reduzir a memória excessiva de bloqueio do sistema para um nível mais razoável . No entanto, alguns designs de aplicativo ou consulta podem acionar o escalonamento de bloqueio em um momento em que não é desejável, e o bloqueio de tabela escalonado pode bloquear outros usuários".

Embora o escalonamento de bloqueio não seja exatamente a mesma coisa que alterar o nível de isolamento em que uma consulta é executada, isso me surpreende porque eu não esperava que o SQL Server recebesse mais bloqueios do que o nível de isolamento padrão permite.