How not to use a background job in a transaction

In modern web applications, transactions and background jobs play an important role to ensure consistency and performance. But sometimes if not used wisely and carefully can end up creating bugs that are difficult to identify in a big application.

While identifying such an issue in an application where we were sending a webhook to an external third party app to cancel an order and update item quantities. But somehow the wrong status was being sent for order along with the wrong quantities.

We identified the discrepancy between the expected and actual data and after crossing off other reasons from our list we realized it was due to the fact that the background jobs were invoked in the transaction.

Model.transaction do
... # some code
cancel_order_and_send_webhook # invokes background job
... # some more code
end

Reason

Now when the method was executed it enqueued a couple of background jobs to send webhooks. So, by the time the jobs ran the transaction wasn’t committed to the database and it used old values for the order and item quantities and hence sending the wrong values in the payload.

Solution

Moving background jobs out of the transaction did the thing and correct values were picked up.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store