Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

run code after transaction commit in Django

Tags:

Is there any way to run some code after transaction commit in Django?

I need to send some messages to a rabbitmq server for offline processing, but the message gets to the consumer before the Django transaction is commited.

My message is sent in the post_save signal of the model. What I'm looking for is a similar mechanism, using signals or something else, that would execute code after the commit (and do nothing if the transaction fails).

I haven't found any generic way of doing it in Django. Do you have any ideas?

like image 596
Grégoire Cachet Avatar asked Jun 04 '09 12:06

Grégoire Cachet


People also ask

How do I commit a transaction in Django?

Django provides the on_commit() function to register callback functions that should be executed after a transaction is successfully committed: on_commit (func, using=None)[source]

Does Django auto commit?

Django's default behavior is to run in autocommit mode. Each query is immediately committed to the database, unless a transaction is active. This means if in a view function there are 2 delete operation and one update then will run one by one and if the last one failed the two fist operation is done to database.

Can't execute queries until the end of the atomic block?

You can't execute queries until the end of the 'atomic' block." is raised when you try to used a database connection after a database exception even those autocommit was set to false from the start. It should be up to the user how to handle the database exception and the transaction as autocommit was set to false.

How does Django handle concurrency?

In terms of Django, optimistic concurrency control can be implemented by overriding the save method on your model class... And, of course, for either of these concurrency mechanisms to be robust, you have to consider transactional control.


1 Answers

django-transaction-hooks solves this problem for Django < 1.9, and the functionality is built into Django 1.9+:

from django.db import transaction  def do_something():     pass  # send a mail, invalidate a cache, fire off a Celery task, etc.  transaction.on_commit(do_something) 
like image 136
Carl Meyer Avatar answered Sep 18 '22 23:09

Carl Meyer