1

Avoir la table, définie par le script [1], j'exécuter des scripts dans 2 fenêtres de SSMSPourquoi UPDATE bloque SELECT sur des lignes non liées?

--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 

et après 1)

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

Indépendamment du niveau d'isolation des transactions en 1) la fenêtre, la SELECT in 2) est bloqué.
Pourquoi?

Le niveau d'isolement de UPDATE a-t-il une influence sur les instructions d'autres transactions?

Le niveau d'isolation le plus élevé est par défaut READ COMMITTED in 2).
Aucun verrou de plage n'est attribué, SELECT doit avoir souffert de problèmes COMMITTED READS (lecture non répétable) et PHANTOM READS (lectures répétables) [2]
Comment le faire souffrir?

Comment faire UPDATE sans bloquer SELECT?

[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]
Copier & coller ou ajouter de fin) après avoir cliqué sur
http://en.wikipedia.org/wiki/Isolation_(database_systems)

Mise à jour:
SELECT AVEC (NOLOCK) n'est pas bloqué ..

Update2:
ou avec , ce qui est le même, LIRE NON CONVENU

Notez que UPDATE est différent de la ligne SELECT.
Même, si le même, ce comportement est en contradiction avec la description des niveaux d'isolement [2]

Les points sont les suivants:

  • suppose que je ne peux pas savoir qui d'autre va SELECT de la même (MISE A JOUR -d) sur la table, mais sans rapport avec la mise à jour des lignes
  • pour comprendre les niveaux d'isolement [2]

SQL Server 2008 R2 Dev

+0

(sélectionnez avec NOLOCK) bloque? –

+0

vouliez-vous dire "-" avec l'indice? –

+0

Que faire si vous utilisez l'indice de mise à jour rowlock? (et en supposant qu'il ne soit pas escaladé ...) –

Répondre

6

Je crois que c'est parce que vous n'avez pas de clé primaire, ce qui, je pense, entraîne une escalade des verrous, bloquant ainsi le SELECT. Si vous ajoutez une PRIMARY KEY dans la colonne ID, vous remarquerez que si vous réessayez, le SELECT renverra les 3 autres lignes maintenant - aucune indication WITH (NOLOCK) n'est nécessaire.

2

Répétition des tests après

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

SELECT 2) est toujours bloqué

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

SELECT 2) n'est pas obstruée

Si modifier 2)

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

montre que 2b) n'est pas bloqué même en l'absence de tout indice ou PK.

Bien que, 2b), sans aucun index, est bloqué après la modification 1) Mise à jour pour fonctionner sous sérialisable mais pas sous REPEATABLE READ ou moins

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

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

Ainsi, il semble que la sélection multiple de la ligne tente d'acquérir verrou non partageable?

Mise à jour:
Eh bien, dans tous les cas de SELECT bloqué, il est en attente d'acquérir
LCK_M_IS bonne raison de uderstand cette cuisine

Update2:
Eh bien, ce n'est pas mise à jour de verrouillage qui est escaladé sur la table, il s'agit de verrous SELECT (partagés) (lorsque SELECT tente de lire plusieurs lignes) sont escaladés à un verrou de table et ne peuvent pas être accordés car la table a déjà un verrou exclusif (UPDATE).

et la présence ou l'absence d'index était sans rapport avec ma question principale

je déplace la discussion sur ce sujet à ma suggestion soumise "Intent rowlocks should not be escalated to a table lock if a table already contains exclusive lock"