Níveis de Isolamento no SQL Server: guia prático com exemplos


Introdução
Concorrência é a arte de manter integridade dos dados enquanto várias transações acontecem ao mesmo tempo. O isolamento determina como leituras e escritas interagem — e, por consequência, o que bloqueia o quê, quando surgem leituras sujas, leituras não repetíveis e “fantasmas”. Abaixo, um guia direto ao ponto com demonstrações práticas e como diagnosticar bloqueios.
Ambiente de demonstração
Crie um banco simples e uma tabela de funcionários para reproduzir os cenários de bloqueio/leitura discutidos ao longo do artigo:
USE master;
GO
CREATE DATABASE LiveDB;
GO
ALTER DATABASE LiveDB SET RECOVERY SIMPLE;
GO
USE LiveDB;
GO
DROP TABLE IF EXISTS dbo.Funcionario;
GO
CREATE TABLE dbo.Funcionario
(
PK int PRIMARY KEY,
Nome varchar(50),
Descricao varchar(100),
[Status] char(1),
Salario decimal(10,2)
);
INSERT dbo.Funcionario VALUES
(1,'Fernando','Gerente','B',5600.00),
(2,'Ana Maria','Diretor','A',7500.00),
(3,'Lucia','Gerente','B',5600.00),
(4,'Pedro','Operacional','C',2600.00),
(5,'Carlos','Diretor','A',7500.00),
(6,'Carol','Operacional','C',2600.00),
(7,'Luana','Operacional','C',2600.00),
(8,'Lula','Diretor','A',7500.00),
(9,'Erick','Operacional','C',2600.00),
(10,'Joana','Operacional','C',2600.00);
GO
READ COMMITTED (padrão) na prática
No padrão do SQL Server, quem escreve bloqueia quem lê e vice-versa. Veja o comportamento em duas conexões:
Conexão 1 – atualizando e deixando a transação aberta
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRAN;
UPDATE dbo.Funcionario SET Salario = 3000.00 WHERE PK = 10;
SELECT * FROM dbo.Funcionario WHERE PK = 10; -- ainda vê 2600 na mesma sessão
-- (transação ainda aberta)
-- ROLLBACK; -- execute depois de testar a Conexão 2
Conexão 2 – tentando ler a mesma linha
SELECT *
FROM LiveDB.dbo.Funcionario -- (se usar WITH (NOLOCK), pode ler dado “sujo”)
WHERE PK = 10;
Resultado esperado:
Sem hint, o
SELECT
fica em blocking (aguarda a Conexão 1 terminar). Isso reflete exatamente o comportamento descrito no conteúdo base:READ COMMITTED
segura lock de leitura apenas durante o comando, mas respeita o lock exclusivo de quem está alterando.Com
WITH (NOLOCK)
/READ UNCOMMITTED
, oSELECT
ignora locks e pode ler o valor “intermediário” (leitura suja), se a transação da Conexão 1 fizer rollback depois.
Diagnosticando blocking (versões antigas e modernas)
Ferramentas rápidas para entender “quem trava quem”:
Compatível com versões antigas (7.0/2000):
EXEC sp_who2;
EXEC sp_lock 53;
EXEC sp_lock 54;
DBCC INPUTBUFFER (53);
DBCC INPUTBUFFER (54);
DMVs (SQL Server 2008+):
SELECT * FROM sys.dm_exec_connections;
SELECT * FROM sys.dm_exec_sessions WHERE session_id > 50; -- sessões de usuário
SELECT * FROM sys.dm_exec_requests WHERE session_id > 50 AND session_id <> @@SPID;
-- Obter o texto T-SQL pelo sql_handle observado em dm_exec_requests:
SELECT * FROM sys.dm_exec_sql_text(0x02000000B5BB8A0D52DAE74382B9972DFC292A98C6A63128);
SELECT * FROM sys.dm_exec_sql_text(0x02000000D0AF75072F185FB122718D72499D4E69233FD990);
Obs: Trocar o código das conexões para o seu ambiente!
Dica: dominar o “ciclo de vida” dos locks e onde buscá-los nas DMVs é essencial para times dev/DBA entenderem e resolverem gargalos de concorrência. O transcript reforça que boa parte dos deadlocks vem de decisões na aplicação (ordem de acesso aos recursos), não “mágica” no banco.
Níveis de isolamento — o que muda?
Resumo prático dos quatro níveis mais usados e os problemas que cada um evita:
READ UNCOMMITTED (ou
WITH (NOLOCK)
): não coloca shared locks para ler, então permite leitura suja, leituras não repetíveis e fantasmas. Evita apenas “lost update” no sentido de não competir comX
de outra sessão, mas é o nível menos seguro.READ COMMITTED (padrão do SQL Server): leitor coloca shared lock durante o comando; se houver exclusive lock, o leitor espera. Evita leitura suja, mas ainda pode haver non-repeatable read e phantoms.
REPEATABLE READ: mantém shared locks nas linhas lidas até o fim da transação, evitando non-repeatable read; ainda assim pode aparecer phantom. (Conceito abordado no transcript ao comparar tempo de retenção de locks por nível.)
SERIALIZABLE: além de reter shared/exclusive até o fim, aplica key-range locks no índice relevante, bloqueando novas linhas que se encaixariam no predicado e, assim, evitando phantoms.
Exemplo clássico de phantom: enquanto um
UPDATE ... WHERE Regiao = 'RJ'
corre, outra sessão insere uma nova venda comRegiao='RJ'
. Com SERIALIZABLE, o SQL Server trava o intervalo no índice da colunaRegiao
, impedindo que essa nova linha apareça como “fantasma” ao final.
Boas práticas rápidas
Escolha o nível por caso de uso: relatórios críticos? Evite leitura suja; considere
SNAPSHOT
/versionamento de linha devidamente avaliado pelo DBA. Trânsito OLTP intenso? Avalie o custo de manter locks por mais tempo. (O material base reforça o trade-off desempenho × integridade à medida que “subimos” o isolamento.)Cuidado com
NOLOCK
: ótimo para não bloquear, péssimo para integridade; use com total consciência do risco.Evite deadlocks na origem: padronize a ordem de acesso aos recursos (mesma sequência em todas as transações) para não criar ciclos; isso é ajuste de aplicação, não de banco.
Conclusão
Entender o comportamento de cada nível e testar os efeitos em cenários reais evita surpresas desagradáveis em produção. Use os scripts acima para montar sua “caixa de areia”, reproduzir bloqueios, observar DMVs e praticar decisões de isolamento mais seguras.
Fui, mas volto com mais SQL Server em breve!
✍️ Sobre o autor
O Prof. Landry é especialista em Microsoft SQL Server desde 1999, Microsoft Trainer, Professor Universitário e criador do canal SQL Server Expert no YouTube, com conteúdo técnico semanal para DBAs e profissionais de dados.
🚀 Quer aprender mais sobre SQL Server?
👉 Me acompanhe no LinkedIn e inscreva-se no canal para não perder nenhuma dica prática!
Subscribe to my newsletter
Read articles from SQL Server Expert directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

SQL Server Expert
SQL Server Expert
O Prof. Landry Duailibe é especialista em Microsoft SQL Server desde 1999, Microsoft Certified Trainer, professor universitário e criador do canal SQL Server Expert no YouTube, onde compartilha conteúdo técnico semanal para DBAs e profissionais de dados. Já ajudou milhares de alunos a evoluírem suas habilidades com SQL Server e conquistarem melhores oportunidades na área de dados.