LCK_M_RX_X Wait Type in SQL Server

LCK_M_RX_X is a wait to acquire an Exclusive Range lock: an exclusive lock on a key value plus an exclusive lock on the range between it and the previous key. Like all range locks it only exists under SERIALIZABLE isolation, where writers must lock the gaps between keys so no other transaction can insert a phantom row into a range.

A session waiting on LCK_M_RX_X is a serializable writer queuing behind other locks on the same key range.

Is It a Problem?

Yes, more often than its shared cousin. Exclusive range locks are a classic deadlock ingredient: two serializable transactions each read a range (taking range-shared locks) and then try to insert or update within it (converting to range-exclusive). Each waits for the other, and the deadlock monitor kills one. If you see LCK_M_RX_X waits alongside deadlock reports, this is almost certainly the pattern.

The upsert idiom IF NOT EXISTS (...) INSERT under serializable, or with HOLDLOCK, is the textbook trigger.

Common Causes

  • Concurrent upserts under serializable isolation on the same key range, often via WITH (SERIALIZABLE) or HOLDLOCK hints inside MERGE or IF EXISTS procedures.
  • Distributed transactions silently promoting sessions to serializable.
  • Queue tables processed by many workers, each range-locking rows as they claim work.
  • Missing indexes on the searched columns, which widens the locked range to the whole table in the worst case.

What To Do

  1. Identify the statements involved via sys.dm_os_waiting_tasks and the deadlock graph in the system_health Extended Events session.
  2. Rework upserts. On modern versions, a plain INSERT ... WHERE NOT EXISTS under READ COMMITTED with a unique constraint plus retry-on-duplicate is simpler and far less deadlock-prone than serializable checks.
  3. Index the key you probe. A seek locks one narrow range; a scan under serializable locks everything it reads.
  4. If serializable is genuinely required, serialize the writers themselves, for example with sp_getapplock, so they queue politely instead of deadlocking.

How To See It

Rank it against everything else with Get-WaitStatistics. Correlate with deadlock counts; the two usually rise together.


Part of the SQL Server Wait Types Library.
Related deep dive: LCK_M_X, LCK_M_S, and LCK_M_U Wait Types.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *