I have multiple threads writing events into a MySQL table events
.
The table has an tracking_no
column configured as auto_increment
used to enforce an ordering of the events.
Different readers are consuming from events
and they poll the table regularly to get the new events and keep the value of the last-consumed event to get all the new events at each poll.
It turns out that the current implementation leaves the chance of missing some events.
This is what's happening:
Thread-1
begins an "insert" transaction, it takes the next value from auto_increment column (1) but takes a while to completeThread-2
begins an "insert" transaction, it takes the next auto_incremente value (2) and completes the write beforeThread-1
.Reader
polls and asks for all events with tracking_number greater than 0; it gets event 2 becauseThread-1
is still lagging behind. The events gets consumed andReader
updates it's tracking status to 2.Thread-1
completes the insert, event 1 appears in the table.Reader
polls again for all events after 2, and while event 1 was inserted it will never be picked up again.
It seems this could be solved by changing the auto_increment
strategy to lock the entire table until a transaction completes, but if possible we would avoid it.