O problema
Eu tenho um par de consultas que, sob isolamento serializável, causam um bloqueio do RX-X. No entanto, quando eu uso Eventos Estendidos para assistir à aquisição de bloqueios, a aquisição de bloqueios RX-X nunca aparece e é liberada apenas. De onde isso vem?
The Repro
Aqui está a minha mesa:
CREATE TABLE dbo.LockTest (
ID int identity,
Junk char(4)
)
CREATE CLUSTERED INDEX CX_LockTest --not unique!
ON dbo.LockTest(ID)
--preload some rows
INSERT dbo.LockTest
VALUES ('data'),('data'),('data')
Aqui está o meu lote problemático:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
INSERT dbo.LockTest
VALUES ('bleh')
SELECT *
FROM dbo.LockTest
WHERE ID = SCOPE_IDENTITY()
--ROLLBACK
Verifico os bloqueios mantidos por esta sessão e vejo o RX-X:
SELECT resource_type, request_mode, request_status, resource_description
FROM sys.dm_tran_locks
WHERE request_session_id = 72 --change SPID!
Mas também tenho um evento estendido em lock_acquired
e lock_released
. Eu filtro-o no associado_object_id apropriado ... não há RX-X.
Depois de executar a reversão, vejo o RX-X (LAST_MODE) liberado, mesmo que nunca tenha sido adquirido.
O que eu tentei
Eu olhei para todos os bloqueios em Eventos Estendidos - sem filtragem. Nenhum bloqueio RX-X adquirido.
Eu também tentei o Profiler: mesmos resultados (exceto, é claro, o nome correto ... não "LAST_MODE").
Eu executei o XE para escalações de bloqueio - não está lá.
Não há XE especificamente para conversões, mas pude confirmar que pelo menos a conversão de bloqueio de U para X é capturada por
lock_acquired
Também digno de nota é o RI-N que é adquirido, mas nunca lançado. Minha hipótese atual é que o RX-X é um bloqueio de conversão, conforme descrito aqui . Existem bloqueios de intervalo de chaves sobrepostos no meu lote que parecem se qualificar para conversão, mas o bloqueio RX-X não está na tabela de conversão.
De onde vem esse bloqueio e por que não é captado pelos Eventos Estendidos?