Billzabob
Async work during Ecto Repo.transaction
During a database transaction, we are spawning a Task. The Task ends up querying the database itself, which leads to a race condition: the transaction may or may not have been committed by the time the Task runs its query.
One solution here is to perform the query before the Task and pass its results into the Task. That way the query is run in the transaction and there is no race condition. The problem here is that we moved the query into the Task for performance reasons; Doing the query synchronously was causing timeouts.
We have tried to figure out a way to have the Task poll the transaction status in the main process and only run once it’s complete, but that seems to be impossible since that info is stored on the process dictionary of the main process.
The way we are currently leaning is to just put a Process.sleep call at the beginning of the Task so that the transaction has time to finish and commit before the Task runs, but that obviously feels super dirty.
Any other suggestions?
Most Liked
benwilson512
This sounds like you want something like Oban, where instead of spawning a task, you would enqueue a job, and then when the transaction commits, that job can be run.
mbuhot
If you’re using Postgres, you could use Listen/Notify to wait for the transaction to complete.
NOTIFYinteracts with SQL transactions in some important ways. Firstly, if aNOTIFYis executed inside a transaction, the notify events are not delivered until and unless the transaction is committed









