Minimal example of using select… for update to isolate rows

后端 未结 1 958
暖寄归人
暖寄归人 2020-12-15 10:22

UPDATE: There is now SKIP LOCKED and NOWAIT for Mysql and Postgres.

Old question follows.


I want concurrent

相关标签:
1条回答
  • 2020-12-15 10:41

    SELECT ... FOR UPDATE locks the row(s) in exclusive mode, which means the second select cannot proceed until the first one has completed or rolled back. This is since the second select's result could be affected by the content of the row you've locked, so it needs to get a read lock to the row to check.

    If you create a UNIQUE INDEX on for example id, you could do;

    select * from SolrCoresPreallocated where id=1 for update;
    

    in the first transaction and;

    select * from SolrCoresPreallocated where id=2 for update;
    

    in the second one independently, since the unique index lets the second select find the correct row without read-locking the first one.

    EDIT: To get a "free" row as quickly as possible, the only way really is to do two transactions;

    • BEGIN/SELECT FOR UPDATE/UPDATE to busy/COMMIT to get the row.
    • BEGIN/<process row>/UPDATE to free/COMMIT to process the row and release it.

    This means that you may need compensating actions in case a process fails and rolls back the transaction that would UPDATE the row to free, but since MySQL (or standard SQL for that matter) doesn't have a notion of "get the next unlocked row", you don't have many options.

    0 讨论(0)
提交回复
热议问题