Jeremy Banks Jeremy Banks - 1 month ago 14
Python Question

May an instance be committed if an exception occurs in the post_save handler?

I have a

post_save
handler that inserts additional records into the database referring to the instance that was just created or updated. However, an error (perhaps a constraint violation) may occur when inserting the additional records.

If an exception occurs in the
post_save
handler, is it still possible that the initial instance will be committed?

The answer might depend on these sub-questions:


  • Does Django's auto-commit mode commit before or after the
    post_save
    signal?

  • Does Django attempt to use nested transactions to rollback the instance being saved if an error occurs in
    post_save
    ?


Answer

According to the docs, if you are using autocommit changes to the initial instance will be committed on .save() before any post_save signal handler. An exception in post_save will not rollback the changes to the initial instance.

You can confirm this by looking at the source to save_base in django/db/models/base.py. The autocommit would occur on line 555 (in 1.4.2), but the post_save signal isn't sent until line 564. You can also see that Django does not attempt to use any nested transactions in .save().

If you are using django.middleware.transaction.TransactionMiddleware and have not overridden its behavior with an autocommit decorator, an exception during post_save would rollback the entire transaction, including the changes to the initial instance.