Consistent read and update without table locking in MySQL/InnoDB
I need t开发者_JS百科o perform the following on MySQL/InnoDB. Assume I have a table consists of 3 cols (id, counter, status)
I need to:
- Select rows where status = 0
- Update them by setting status = 1, and increment counter by 1
- 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 (...)
精彩评论