W dniu 22.06.2011 00:21, Michael Hudson-Doyle pisze:
Fortunately django almost never runs in autocommit mode. There is an implicit transaction around the whole request. It is easy to control the transaction processing around a piece of code, see [1].
I got very confused by this, I admit. In general, calling .save() on a model does a COMMIT, unless you're managing the transactions yourself (or using TransactionMiddleware)?
Something like that.
It's easier to read the source than read my explanations. django.db.models.base:Model.base_save() calls transaction.commit_unless_managed().
In practice, django is almost always managed so save is never commits. The transaction middleware you mentioned makes django views "managed" using commit_on_success decorator on the request method. You need to disable that manually and I don't see any reason why someone would such a thing.
And of course, the way this is being done in the scheduler at the moment is not part of the web app, so the "usual" stuff doesn't always apply.
On PostgreSQL we also need to properly implement handling of IngegrityError as it differs significantly from SQLite [2]
It's just that it dooms transactions, right?
Not really, it just makes supporting them a little trickier. I do that with deserialization of bundles. In practice it's quite easy if you remember to use save points correctly. See my 1-4 points below for explanation why.
The approach we'll take on
integrity errors is to rollback and retry so that's easy.
You can rollback to a savepoint.
(it's confusing that https://docs.djangoproject.com/en/dev/topics/db/transactions/#transaction-ro... says that the changes made by a.save() will be lost when the default is for .save() to commit, so they must be assuming that you're using TransactionMiddleware).
It's not only transaction middleware. Any code that earlier (in the call history of a particular function) enabled transactions will behave this way.
In reality this is all manageable:
1) Proper code will work regardless autocommit mode :-) 2) PostgreSQL does not break things, you just need to take account for savepoints. 3) Handling transactions manually implies you use savepoints and thus get 1 and 2 right. 4) Handling transactions automatically (around a view) implies you get shielded from most of the complexity, if your actual application logic is happy not to use explicit manual transactions in such cases.
Best regards ZK