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.
I think I understand now. It's BEGIN IMMEDIATE
solving the problem by making another BEGIN IMMEDIATE
wait.