Search code examples
ruby-on-railsrubythread-safetyrace-conditionsidekiq

Race condition when updating a field in Sidekiq


I have a concurrency of two threads in Sidekiq and at one point I call the following method in one of my models:

def update_pending
  update(pending_stats: self.pending_stats + 1)
end

I would expect that when both jobs finish, the pending_stats attribute is two, but it is just one, even though both threads call that method.

How can I make sure that the two threads update actually with the correct value?


Solution

  • Try using increment_counter which is an atomic operation.

        def update_pending
          increment_counter(:pending_status, 1)
        end
    

    This would execute following SQL:

        UPDATE ...
        SET pending_status = COALESCE(pending_status, 0) + 1
        WHERE ...