Estoy configurando un caso de prueba para probar un cierto escenario de punto muerto y necesito una idea de lo que está sucediendo. Tengo una tabla de montón, llamada convenientemente HeapTable. Esta tabla se actualiza mediante 2 transacciones de manera simulada.
Transacción 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
Transacción 2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
Primero disparo la transacción 1, seguida de cerca por la transacción 2. Como se esperaba, la transacción 1 reclamará algunos bloqueos exclusivos, junto con algunos intentos exclusivos. La transacción 2 entrará y solicitará un bloqueo de actualización en el mismo 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
Me sorprendió ver que la segunda transacción solicita un bloqueo de actualización en el mismo RID, ya que pensé que esto apuntaba a un solo registro y ambas declaraciones de actualización manejan datos diferentes. De alguna manera esperaba un conflicto a nivel de página.
Cuando la segunda actualización de la transacción 1 se inicia en la transacción 2 se verá como una víctima de punto muerto que dará como resultado una reversión de la transacción 2 y la finalización de la transacción 1.
¿Alguien puede explicarme por qué la segunda transacción requeriría un bloqueo de actualización en el mismo RID a pesar de actualizar un registro diferente?
Sé cómo solucionar esto (por ejemplo, con un índice). No estoy buscando una solución, en realidad estoy buscando una explicación de por qué 2 actualizaciones que manejan diferentes registros en un montón querrían bloquear el mismo RID. Estoy usando el aislamiento de lectura comprometida. No hay índices no agrupados en la tabla.