简体   繁体   中英

Consistent read and update without table locking in MySQL/InnoDB

I need to perform the following on MySQL/InnoDB. Assume I have a table consists of 3 cols (id, counter, status)

I need to:

  1. Select rows where status = 0
  2. Update them by setting status = 1, and increment counter by 1
  3. Return the selected/updated id to client

Requirements:

  • The rows to be update must exactly the same with selected, even new rows has been added after the 1st select
  • No duplicated update on a row is allowed, even multiple scripts are running on the same data at the same time

What would be the best solution in term of performance and scalability (work for large table)?

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT  id
FROM    mytable
WHERE   status = 0
FOR UPDATE;
UPDATE  mytable
SET     status = 1,
        cnt = cnt + 1
WHERE   status = 0;
COMMIT;

You can select and update in one statement, which should execute atomically:

UPDATE tbl SET status=1, counter=counter+1 WHERE status=0;

I don't know what you want in step 3, since more than one id is involved. Do you want a table of id rows as from a SELECT statement? If so, you can perhaps use a stored procedure, or else use SELECT ... LOCK IN SHARE MODE

You can do

SELECT  id
FROM    mytable
WHERE   status = 0
FOR UPDATE;

Then build list of ids in your software and then do

UPDATE  mytable
SET     status = 1,
        cnt = cnt + 1
WHERE   id IN (...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM