Il problema
Ho un paio di query che, in isolamento serializzabile, causano un blocco RX-X. Tuttavia, quando utilizzo gli eventi estesi per guardare l'acquisizione del blocco, l'acquisizione del blocco RX-X non viene mai visualizzata, viene solo rilasciata. Da dove proviene?
The Repro
Ecco il mio tavolo:
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')
Ecco il mio problema batch:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
INSERT dbo.LockTest
VALUES ('bleh')
SELECT *
FROM dbo.LockTest
WHERE ID = SCOPE_IDENTITY()
--ROLLBACK
Controllo i blocchi mantenuti da questa sessione e vedo RX-X:
SELECT resource_type, request_mode, request_status, resource_description
FROM sys.dm_tran_locks
WHERE request_session_id = 72 --change SPID!
Ma ho anche un evento esteso su lock_acquired
e lock_released
. Lo filtro sull'appropriato associate_object_id ... non c'è RX-X.
Dopo aver eseguito il rollback, vedo RX-X (LAST_MODE) rilasciato, anche se non è mai stato acquisito.
Quello che ho provato
Ho esaminato tutti i blocchi in Eventi estesi - nessun filtro. Nessun blocco RX-X acquisito.
Ho anche provato Profiler: stessi risultati (tranne ovviamente ottiene il nome giusto ... no "LAST_MODE").
Ho eseguito l'XE per le escalation dei blocchi - non è lì.
Non esiste XE specifico per le conversioni, ma sono stato in grado di confermare che almeno la conversione del blocco da U a X è stata acquisita
lock_acquired
Da notare anche il RI-N che viene acquisito ma mai rilasciato. La mia attuale ipotesi è che l'RX-X sia un blocco di conversione, come descritto qui . Nel mio batch sono presenti blocchi sovrapposti di intervalli di chiavi che sembrano idonei per la conversione, ma il blocco RX-X non si trova nella tabella di conversione.
Da dove proviene questo lucchetto e perché non viene raccolto da Extended Events?