On Friday, March 1, 2013 at 7:48 AM, Aymeric Augustin wrote: > Hello, > > I'd like to improve transactions handling in Django. The first step is the > current emulation of autocommit with database-level autocommit. > > ** Rationale ** > > PEP249 says that any SQL query opens a transaction and that it's the > application's job to commit (or rollback) changes. This model is also > required by the SQL standard. But it isn't very developer-friendly. > > To alleviate the pain, Django commits after each ORM write. Unfortunately, > this means that each read opens a transaction, that eventually gets committed > after the next write, or rolled back at the end of the query. Such > transactions are useless and don't come for free. Relying on them to enforce > integrity is extremely fragile — what if an external library starts writing > to a log table in the middle of one of these implicit transactions? The term > "footgun" comes to mind. > > Database authors have reached the same conclusion, and most databases > supported by Django use autocommit by default, ignoring the SQL standard. On > PostgreSQL and SQLite, this is the only mode available. > > As a consequence, to implement the behavior mandated by PEP 249, the Python > libraries (psycopg2, sqlite3, etc.) automatically start transactions. And > then Django automatically commits them. This is not only wasteful, but also > buggy. It's the root cause of "idle in transaction" connections on > PostgreSQL. It's also sometimes poorly implemented: for instance, executing > "SAVEPOINT …" on SQLite commits implicitly. (It's arguably a bug in the > design of the sqlite3 module. The Python bug tracker suggests it's going to > be documented.) > > Basically, Django intends to provide autocommit by default. Rather than fight > the database adapter that itselfs fights the database, I propose to simply > turn autocommit on, and stop implicitly starting and committing transactions. > Explicit is better than implicit. > > ** Implementation ** > > All databases supported by Django provide an API to turn autocommit on: > > - http://initd.org/psycopg/docs/connection.html#connection.autocommit > - http://docs.python.org/2/library/sqlite3#sqlite3.Connection.isolation_level > - http://mysql-python.sourceforge.net/MySQLdb.html => conn.autocommit() > - http://cx-oracle.sourceforge.net/html/connection.html#Connection.autocommit > > This obviously has far-reaching consequences on transaction handling in > Django, but the current APIs should still work. (Fixing them is part 2 of the > plan.) The general idea is that Django will explicitly start a transaction > when entering transaction management. > > This will obviously impact maintainers of backend for other databases, but if > it works on Oracle (which doesn't have autocommit — it's emulated in OCI) and > on PostgreSQL (which enforces autocommit), I hope it can work anywhere. > > ** Backwards-compatibility ** > > Roughly, I'd classify Django users in four groups: > 1 - "Transactions, how do they work?" > 2 - "Django autocommits, doesn't it?" > 3 - "I'm using TransactionMiddleware!" > 4 - "I'm managing my transactions." > > Groups 1 and 2 won't see the difference. There won't be any difference for > group 3. Group 4 may be impacted by the change, but I believe most people in > this category have autocommit turned on already — or would like to, if > they're on MySQL — and will understand the change. > > I don't see much point in providing an option to turn autocommit off, because > starting a transaction is a much more explicit way to achieve the same > effect. We usually don't provide "backwards compatibility with bugs". > > Yay or nay? +1 > > -- > Aymeric. > > > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected] > (mailto:[email protected]). > To post to this group, send email to [email protected] > (mailto:[email protected]). > Visit this group at http://groups.google.com/group/django-developers?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > >
-- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
