Pergunta

Tendo a tabela, definida pelo script [1], executo scripts em 2 janelas de SSMS

--1) first in first SSMS window
set transaction isolation level READ UNCOMMITTED;
begin transaction;
update aaa set Name ='bbb' 
    where id=1;
-- results in "(1 row(s) affected)"
--rollback

e depois de 1)

--2)after launching 1)
select * from aaa --deleted comments
where id<>1
--is blocked

Independentemente no nível de isolamento da transação em 1) janela, a seleção em 2) é bloqueada.
Por quê?

O nível de isolamento para atualização tem alguma influência sobre declarações sobre outras transações?

O nível de isolamento mais alto é a leitura padrão comprometida em 2).
Nenhuma bloqueio de alcance é atribuída, a Select deveria ter sofrido leituras comprometidas (leituras não repetíveis) e leituras fantasmas (leituras repetíveis) Problemas [2
Como fazê -lo sofrer?

Como a atualização pode ser feita sem bloquear selecionar?

[1]

CREATE TABLE aaa
(
    Id int IDENTITY(1,1) NOT NULL,
    Name  varchar(13) NOT NULL
)


insert into  aaa(Name) 
   select '111' union all 
   select '222' union all 
   select '333' union all 
   select '444' union all 
   select '555' union all 
   select '666' union all 
   select '777' union all 
   select '888'  

[2]
Copiar e colar ou adicionar à direita) ao clicar
http://en.wikipedia.org/wiki/isolation_(database_systems)

Atualizar:
Selecionar com (Nolock) não está bloqueado ...

Update2:
ou com, o que é o mesmo, leia não comprometido

Observe que a atualização é diferente da linha selecionada.
Mesmo, se o mesmo, esse comportamento contradiz à descrição dos níveis de isolamento [2

Os pontos são isso:

  • Suponha que eu não possa saber quem mais vai selecionar da mesma tabela (atualização-d), mas não relacionada a atualizar linhas
  • para entender os níveis de isolamento [2

SQL Server 2008 R2 Dev

Foi útil?

Solução

Eu acredito que é porque você não tem uma chave primária, o que eu acho que está resultando na escalada das bloqueios, bloqueando a seleção. Se você adicionar uma chave primária à coluna ID, notará que, se tentar novamente, a seleção retornará as outras 3 linhas agora - não com a dica (Nolock) necessária.

Outras dicas

Repetindo testes depois

--3)
create index IX_aaa_ID on aaa(id)

Selecionar 2) ainda está bloqueado

--4)
drop index IX_aaa_ID on aaa
create unique index IX_aaa_ID on aaa(id)
--or adding primary key constraint   

Selecione 2) não está bloqueado

Se modificar 2) como

--2b)
select * from aaa 
    where id=3 
    --or as
    --WHERE id=2 

mostra que 2b) não é bloqueado mesmo na ausência de qualquer índice ou PK.

Porém, 2b), sem qualquer índice, é bloqueado após modificar 1) atualização para executar em serializável, mas não sob leitura repetível ou inferior

--1c)  
set transaction isolation level serializable;
--set transaction isolation level REPEATABLE READ;

begin transaction;
update aaa set Name ='bbb' 
    where id=1;
--rollback

Então, parece que várias tentativas de seleção de linhas de adquirir bloqueio não compartilhável?

Atualizar:
Bem, em todos os casos de seleção, está esperando para adquirir lck_m_is
Boa razão para usar esta cozinha

Update2:
Bem, não é o bloqueio de atualização que está escalado na tabela, é selecionado (compartilhado) bloqueios (quando selecionados tenta ler várias linhas) são escalados para uma trava de tabela e não podem ser concedidos porque a tabela já foi exclusiva (atualização).

E presença ou ausência de índice não estava relacionada à minha pergunta principal

Eu mudo a discussão deste tópico para minha sugestão enviada "As intenções de rowlocks não devem ser escaladas para uma trava de mesa se uma tabela já contiver bloqueio exclusivo"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top