Perché AGGIORNARE i blocchi di SELEZIONARE estraneo righe?
-
25-09-2019 - |
Domanda
Avendo la tabella, definita dallo script [1], l'esecuzione di script in 2 finestre di 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 dopo 1)
--2)after launching 1)
select * from aaa --deleted comments
where id<>1
--is blocked
In modo indipendente su un livello di isolamento delle transazioni in 1) finestra, SELEZIONA 2) viene bloccata.
Perché?
Non a livello di isolamento per AGGIORNARE alcuna influenza sulle dichiarazioni su altre operazioni?
Il più alto livello di isolamento è di default LEGGERE IMPEGNATI in 2).
No blocchi di intervallo sono attribuiti, SELEZIONARE deve avere sofferto COMMESSO LEGGE (Letture non RIPETIBILI) e LETTURE FANTASMA (Ripetibile Legge) problemi [2]
Come fare soffrire?
Come si può AGGIORNARE essere fatto senza il blocco SELEZIONARE?
[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]
Copia&incolla o aggiungere finale ) cliccando
http://en.wikipedia.org/wiki/Isolation_(database_systems)
Aggiornamento:
SELEZIONARE CON(NOLOCK) non è bloccato...
Update2:
o, che è lo stesso, READ UNCOMMITTED
Si noti che l'AGGIORNAMENTO è diverso da SELEZIONARE riga.
Anche se, lo stesso, questo comportamento contraddice la descrizione dei livelli di isolamento [2]
I punti sono:
- supponiamo che io non so chi altro sta andando a SELEZIONARE le stesse (UPDATE-d) tabella ma estraneo aggiornamento delle righe
- per capire i livelli di isolamento [2]
SQL Server 2008 R2 Dev
Soluzione
Credo che sia perché non si dispone di una chiave primaria, che credo si traduce nelle serrature essere intensificati, quindi bloccando il SELECT. Se si aggiunge una chiave primaria nella colonna ID, si noterà che se si tenta di nuovo, SELECT restituirà gli altri 3 righe ora -. No CON (NOLOCK) suggerimento necessario
Altri suggerimenti
Ripetendo il test dopo
--3)
create index IX_aaa_ID on aaa(id)
SELEZIONARE 2) è ancora bloccato
--4)
drop index IX_aaa_ID on aaa
create unique index IX_aaa_ID on aaa(id)
--or adding primary key constraint
SELEZIONARE 2) NON è bloccato
Se per modificare 2) come
--2b)
select * from aaa
where id=3
--or as
--WHERE id=2
mostra che, 2b) non è bloccato anche in assenza di un qualsiasi indice o PK.
Però, 2b), senza indici, è stato bloccato dopo la modifica 1) AGGIORNAMENTO per l'esecuzione in serializable ma non sotto REPEATABLE READ o inferiore
--1c)
set transaction isolation level serializable;
--set transaction isolation level REPEATABLE READ;
begin transaction;
update aaa set Name ='bbb'
where id=1;
--rollback
Così, sembra più la selezione della riga tenta di acquisire non condivisibile blocco?
Aggiornamento:
Bene, in tutti i casi di SELEZIONARE bloccato è in attesa di acquisire LCK_M_IS
Buon motivo per uderstand questa cucina
Update2:
Beh, non è blocco di AGGIORNAMENTO che è sfociata nella tabella, SELEZIONARE (in comune) blocca (quando si SELEZIONA cerca di leggere più righe) sono passato a un blocco di tabella e non può essere concessa perché la tabella è già esclusiva (AGGIORNAMENTO) di blocco.
E la presenza o assenza di indice è stato correlato alla mia domanda principale
Sposto la discussione di questo argomento per la mia presentate suggerimento "L'intento scalmi non dovrebbe essere l'escalation di un blocco di tabella se una tabella contiene già un blocco esclusivo"