Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force Rails ActiveRecord to commit a transaction flush

Is it possible to force ActiveRecord to push/flush a transaction (or just a save/create)?

I have a clock worker that creates tasks in the background for several task workers. The problem is, the clock worker will sometimes create a task and push it to a task worker before the clock worker information has been fully flushed to the db which causes an ugly race condition.

Using after_commit isn't really viable due to the architecture of the product and how the tasks are generated.

So in short, I need to be able to have one worker create a task and flush that task to the db.

like image 726
Jason Ellis Avatar asked May 09 '14 22:05

Jason Ellis


1 Answers

ActiveRecord uses #transaction to create a block that begins and either rolls back or commits a transaction. I believe that would help your issue. Essentially (presuming Task is an ActiveRecord class):

Task.transaction do
  new_task = Task.create(...)
end

BackgroundQueue.enqueue(new_task)

You could also go directly to the #connection underneath with:

Task.connection.commit_db_transaction

That's a bit low-level, though, and you have to be pretty confident about the way the code is being used. #after_commit is the best answer, even if it takes a little rejiggering of the code to make it work. If it won't work for certain, then these two approaches should help.

like image 116
Cyberfox Avatar answered Oct 11 '22 16:10

Cyberfox