﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
37369	on_commit should raise an error when no transaction is open	Charlie Denton		"When calling `on_commit` outside of a transaction, Django will execute the callback immediately. This is a documented feature. See https://docs.djangoproject.com/en/6.1/topics/db/transactions/#performing-actions-after-commit

This leads to misleading code which looks as though it will defer work when it will not. For example, it masks issues where `on_commit` is called with a different `using=` argument to the transaction which is currently open. (Either the transaction was opened on the wrong DB, or the callback is waiting on the wrong database.)

Instead, it would make sense to adopt the behaviour of Django Subatomic's `run_after_commit`, which raises an error when `on_commit` is called outside of a transaction. After all, there will be no `COMMIT` when there is no open transaction.

This idea was suggested when `on_commit` was introduced, but was seemingly not addressed. See:

- https://github.com/django/django/pull/4593#issuecomment-98496218
- https://github.com/django/django/pull/4593#issuecomment-98762940

This has been discussed at Django on the Med 2026. The approach that was suggested to me was:

Step 1:

- Change `on_commit` to raise an error when it is called without an open transaction.
- Add a temporary setting to opt out of the new behaviour (and emit a warning when `on_commit` is called with no transaction).

Step 2:
- Remove the opt-out setting.

To prevent a situation where code passes in tests but fails in production, we should explicitly ignore the transaction created by the test suite when checking if a transaction is open. Django Subatomic does this check using a utility function: `in_transaction`. I believe that function would be a useful addition to Django's API. See https://kraken-tech.github.io/django-subatomic/v2.0.0/reference/django_subatomic/db/#django_subatomic.db.in_transaction and https://github.com/django/new-features/issues/147.

The `in_transaction` API will enable developers who want to run the callback immediately if there is no transaction:

{{{#!python
if in_transaction():
    on_commit(my_callback)
else:
    my_callback()
}}}
"	New feature	new	Database layer (models, ORM)	6.1	Normal			Charlie Denton	Accepted	0	0	0	0	0	0
