litements / litequeue

Queue built on top of SQLite

Home Page:https://litements.polyrand.net/queue/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What are the guarantees of _pop_transaction? Same item being returned twice race condition, possible?

tomekit opened this issue · comments

I am looking on the _pop_transaction and wondering how it works and what guarantees it has.

In order for it to pop the item it executes this:

BEGIN IMMEDIATE

SELECT message, message_id FROM Queue
            WHERE rowid = (SELECT min(rowid) FROM Queue
                           WHERE status = 0)

UPDATE Queue SET status = 1, lock_time = strftime('%s','now') WHERE message_id = :message_id AND status = 0

Assuming there is more than one worker that pops the items from the queue, is it possible for them to SELECT the same message_id? If that happens then they would both try to UPDATE the status to 1.
Only one of them would actually do the actual row update, since there is WHERE status = 0 check, so the first UPDATE wins... but in fact shouldn't the code check the result: select changes(); to discard the item which actually hasn't effectively updated DB?

What's the role of IMMEDIATE locking here by the way? I've just started looking on the SQLite project and come from the MySQL background, pardon my lack of experience.