O problema
Eu tenho um par de consultas que, sob isolamento serializável, causam um bloqueio RX-X. No entanto, quando uso Extended Events para assistir a aquisição de bloqueio, a aquisição de bloqueio RX-X nunca aparece, apenas é liberada. De onde isso vem?
A reprodução
Segue minha tabela:
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 de problemas:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
INSERT dbo.LockTest
VALUES ('bleh')
SELECT *
FROM dbo.LockTest
WHERE ID = SCOPE_IDENTITY()
--ROLLBACK
Eu verifico os bloqueios mantidos por esta sessão e vejo 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 o filtro no associado_object_id apropriado... não há RX-X.
Após executar o rollback, vejo o RX-X (LAST_MODE) liberado, mesmo que nunca tenha sido adquirido.
O que eu tentei
Olhei para todos os bloqueios em Eventos Estendidos - sem filtragem. Nenhum bloqueio RX-X adquirido.
Eu também tentei Profiler: mesmos resultados (exceto, é claro, que obtém o nome certo ... sem "LAST_MODE").
Eu executei o XE para escalonamentos 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 . Há 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?