On 9 mars 2013, at 00:51, Florian Apolloner <[email protected]> wrote:

> If you don't care about the timeframe I'd like to smoke test it on 
> Postgresql,  Mysql, Oracle on Tuesday (again -- due to an exam I won't have 
> time for earlier tests [although I am pretty sure postgres and mysql are in a 
> good shape after my previous tests]). In the worst case scenario I'd ask you 
> to give me till the 16th.

I'd like to merge it before the PyCon sprints to get some feedback and to avoid 
blocking development on the ORM.

> I'd also like to ask if we really want to have savepoints as default.

savepoint=False is primarily designed for internal use in Django. I hesitated 
before making it a public API; finally I documented it because I thought people 
would discover it anyway.

Anssi made a benchmark with 1000 raw SQL updates: 
https://code.djangoproject.com/ticket/2227#comment:34 Adding a savepoint around 
each query made it run 2.5x slower. (I don't know if he was updating the same 
object; if he was, that's very pathological, because it can all be done in 
memory without savepoints, while it requires syncing every request to disk with 
savepoints.) Anyway, without savepoint=False, Django could become slower on 
large series of operations that require being in a transaction, like 
multi-table saves.

Now, in your own code, if you're looping on 1000 operations, and you feel 
concerned about SQL performance, I expect you to write this:

with transaction.atomic():              # do all the inserts in a transaction 
and commit only once (faster)
    for i in range(1000):
        MyModel.objects.create(…)

Not this:

for i in range(1000):
    with transaction.atomic():          # WTF?
        MyModel.objects.create(…)

The point of savepoint=False is to prevent Django from implicitly doing the 
latter. It's only useful for constructs where the overhead of the savepoint 
becomes noticeable, ie. fast queries that are likely to be executed in a loop.

> Looking at my pluggable projects I'll usually have @atomic(savepoints=False) 
> around __every__ complex view since I don't know if ATOMIC_REQUESTS will be 
> true or false. Even if I use it as context manager most views won't care 
> about transactions vs savepoints, so in most cases ensuring a transaction at 
> all should be enough.


In non-trivial cases, the overhead of the savepoint will not even be 
measurable, and it provides more natural error handling. I've forgotten to 
document it; I'll do it now.

The savepoint guarantees that you can always go ahead after:

try:
    with transaction.atomic():
        do_stuff()
except ...:
    handle_exception()

See also 
https://docs.djangoproject.com/en/dev/topics/db/transactions/#savepoint-rollback

-- 
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].
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.


Reply via email to