Je suis en train de mettre en place un cas de test pour prouver un certain scénario de blocage et j'ai besoin d'avoir un aperçu de ce qui se passe. J'ai une table de tas, appelée de manière conventionnelle HeapTable. Ce tableau est mis à jour par 2 transactions simulées.
Transaction 1:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';
WAITFOR DELAY '00:00:15';
UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';
ROLLBACK TRANSACTION
Transaction 2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
Je déclenche d'abord la transaction 1, suivie de près par la transaction 2. Comme prévu, la transaction 1 réclamera des verrous exclusifs, ainsi que des verrous exclusifs intentionnels. La transaction 2 entrera et demandera un verrou de mise à jour sur le même RID:
spid dbid ObjId IndId Type Resource Mode Status
55 5 711673583 0 RID 1:24336:10 X GRANT
57 5 711673583 0 RID 1:24336:10 U WAIT
J'ai été un peu surpris de voir la deuxième transaction demander un verrou de mise à jour sur le même RID, car je pensais que cela pointait vers un seul enregistrement et que les deux instructions de mise à jour traitaient des données différentes. Je m'attendais en quelque sorte à un conflit au niveau de la page.
Lorsque la deuxième mise à jour de la transaction 1 démarre dans la transaction 2, elle sera considérée comme une victime de blocage entraînant un retour en arrière de la transaction 2 et l'achèvement de la transaction 1.
Quelqu'un peut-il m'expliquer pourquoi la deuxième transaction nécessiterait un verrou de mise à jour sur le même RID bien que la mise à jour d'un enregistrement différent?
Je sais comment résoudre ce problème (par exemple avec un index). Je ne cherche pas de correctif, je cherche en fait une explication pour laquelle 2 mises à jour gérant différents enregistrements dans un tas voudraient verrouiller le même RID. J'utilise l'isolement de lecture engagée. Il n'y a aucun index non cluster sur la table.
la source