Estou configurando um caso de teste para provar um determinado cenário de conflito e exigir algumas dicas sobre o que está acontecendo. Eu tenho uma tabela de pilha, conventientemente chamada HeapTable. Esta tabela é atualizada por 2 transações simultaneamente.
Transação 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
Transação 2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
Eu aciono a transação 1 primeiro, seguida de perto pela transação 2. Como a transação esperada 1 reivindicará alguns bloqueios exclusivos, juntamente com outros de intenção. A transação 2 entrará e solicitará um bloqueio de atualização no mesmo 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
Fiquei meio surpreso ao ver a segunda transação solicitar um bloqueio de atualização no mesmo RID, pois achei que isso apontava para um único registro e as duas instruções de atualização lidam com dados diferentes. De alguma forma, eu esperava um conflito no nível da página.
Quando a segunda atualização da transação 1 iniciar a transação 2 será vista como vítima de impasse, resultando em uma reversão da transação 2 e na conclusão da transação 1.
Alguém pode me explicar por que a segunda transação exigiria um bloqueio de atualização no mesmo RID, embora a atualização de um registro diferente?
Eu sei como consertar isso (por exemplo, com um índice). Não estou procurando uma correção, na verdade, estou procurando uma explicação sobre por que 2 Atualizações que manipulam registros diferentes em um heap desejam bloquear o mesmo RID. Estou usando o isolamento confirmado por leitura. Não há índices não clusterizados na tabela.