Thank you for summarizing the issue.
Unfortunately, I don’t think we can change BEGIN IMMEDIATE
without a way to opt-in into this behaviour as even if we put the performance aspect aside it has the potential of breaking read heavy applications out there as Aymeric pointed out when closing the ticket.
The ATOMIC_REQUEST
setting is not special by any mean, it just manually wrap views in an atomic
blocks so I don’t think it warrants special casing. It just happen to a common case that could be problematic.
Given Django doesn’t event support passing an isolation_level
to atomic
I’m also not convinced that allowing to specify immediate
under a serializable isolation mode (e.g. it could result in NOT DEFERRABLE
on Postgres and IMMEDIATE
on SQLite`) is also going to fly.
At this point I think the only acceptable solution, assuming this gets some traction (this issue has seen no activity for over 5 years) would be to allow specifying whether or not all transaction start should be immediate though an OPTIONS
which is what I assume Aymeric was alluding to
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 08de0bad5a..ce9eab8d9d 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -297,7 +297,12 @@ def _start_transaction_under_autocommit(self):
Staying in autocommit mode works around a bug of sqlite3 that breaks
savepoints when autocommit is disabled.
"""
- self.cursor().execute("BEGIN")
+ sql = (
+ "BEGIN IMMEDIATE"
+ if self.settings_dict["OPTIONS"].get("begin_immediate")
+ else "BEGIN"
+ )
+ self.cursor().execute(sql)
def is_in_memory_db(self):
return self.creation.is_in_memory_db(self.settings_dict["NAME"])