1

This table is used as a message queue with multiple readers and writers:

CREATE TABLE IF NOT EXISTS MyQueue(
id CHAR(36) PRIMARY KEY NOT NULL, 
at DateTime NOT NULL, 
message TEXT NOT NULL, 
INDEX(at ASC));

I try to prevent double reading of the messages by using update locks:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT message FROM MyQueue WHERE at <= @today ORDER BY at ASC LIMIT 1 FOR UPDATE;
UPDATE MyQueue SET at=@nextDay WHERE at <= @today ORDER BY at ASC LIMIT 1;

(Idea is to remove message latter today after successful processing by one of the readers or reprocess tomorrow.)

But it looks like that some double reads are still possible. What to pay attention to?

1
  • 1
    1) Your DDL does not guarantee that selected record and updated record is the same - at field is not unique. 2) Perform this action as one query, not 2 separate ones. Commented Mar 25, 2020 at 7:39

1 Answer 1

1

It helped to wrap the query into the Tx:

START TRANSACTION;
SELECT id, at, message FROM {Table} WHERE at <= @now ORDER BY at ASC LIMIT 1 FOR UPDATE;
UPDATE {Table} SET at=@timeout WHERE at <= @now ORDER BY at ASC LIMIT 1;
COMMIT;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.