Django · Transactions
Django on_commit: Trigger Side Effects After the Database Commits
Defer task publication and notifications until a transaction succeeds, while keeping delivery guarantees explicit.

Saving a model inside an atomic block does not mean the transaction has committed. A later failure can roll back that write while an email or background task has already escaped.
Register the side effect
Use transaction.on_commit to register a callable after creating the record. For example, inside transaction.atomic(), create an order and register transaction.on_commit(partial(enqueue_order, order.pk)), after importing partial from functools. Here, enqueue_order is your application’s task-publishing function.
Understand rollback
The callback runs after the open transaction commits successfully. A rollback discards it. A callback registered inside a nested atomic block still waits for the outer transaction, and rollback to its savepoint can discard it.
Know the limits
Outside an active transaction, on_commit runs immediately. Callback failure does not undo the committed database changes. This hook is therefore not a durable delivery guarantee: a process failure or unavailable task broker still needs an explicit recovery strategy.
Test the boundary
Use TestCase.captureOnCommitCallbacks() to inspect registered callbacks in Django tests. Cover successful registration and rollback behavior, and verify that the callback receives stable identifiers rather than relying on mutable request state. Keep the transaction short and the callback’s responsibility clear.