Engine Atlas

MySQL Locking Reads: SELECT ... FOR UPDATE and Next-Key Locks

locking read · next-key interval · data_locks
MySQL 8.4.10captured evidence
한국어

Execution variant
At a glanceBefore · waiting · after COMMIT
Summary
C UPDATE + B INSERT waiting
What does this query do?

It reads task rows where tenant_id = 7 and priority is at least 20 and below 40.

Foundjob_id 102, 103

Session A locks the matched rows and the index gap between them, so both the job_id 103 UPDATE and job_id 106 INSERT wait for COMMIT.

Run the same SELECT in three conditions and compare whether Session B's INSERT and Session C's UPDATE run immediately or wait for COMMIT.

Current condition
REPEATABLE READ + SELECT ... FOR UPDATE
Session A
Session A · runs SELECT
Session B
Session B · tries INSERT
Session C
Session C · tries UPDATE
1

Before Session A runs SELECT

The WHERE clause reads lock_jobs rows for tenant_id = 7, then keeps only rows whose priority is at least 20 and below 40.

Query range
tenant_idpriorityjob_id
710101
720102
730103
740104
750105
tenant_id = 7 · priority >= 20 · priority < 40
2

After Session A runs SELECT

Session A reads job_id 102 and 103 and keeps FOR UPDATE locks. Session C waits on the job_id 103 row lock, and Session B waits on the index gap for priority 25.

SELECT ... FOR UPDATE
  • job_id 102tenant_id 7 · priority 20
  • job_id 103tenant_id 7 · priority 30
Session C · UPDATE job_id 103
Waiting until A commits
Session B · INSERT job_id 106, priority 25
Waiting until A commits
3

After Session A commits

After Session A commits, the locks are released and the waiting UPDATE and INSERT complete.

  • UPDATED · job_id 103
  • INSERTED · job_id 106
tenant_idpriorityjob_idstate
720102UNCHANGED
725106INSERTED
730103UPDATED