On 29 touko, 01:07, Chris Conover <clc...@gmail.com> wrote: > Adding commit_unless_managed() before the get() seems to fix the problem. > Looking at it locally, the Gearman worker starts a transactions and just > calls commit when the processing is done, over and over, never starting a > new transaction. That combined with REPEATABLE-READ seems to be the culprit. > > My next step was going to be to set the isolation level to READ-COMMITTED > which would probably have fixed it as well. Thought I'm not sure how that > would have affected performance. > > Will the changes to transactions in 1.6 possibly address this issue so I > can remove the commit_unless_managed() call? It looks like the major change > is using the underlying database's autocommit mode rather than emulating it > in the ORM. I suppose I'll have to test...
The thing is Django didn't even emulate the autocommit mode in pre 1.6 versions. The behavior in 1.5 is this: 1. Any query will start a transaction (unless of course you are already in transaction) 2. An ORM write will commit after the write is done (but not rollback on exception!) 3. Any other write will not commit This is changed to: 1. Any query will happen in autocommit mode - that is there are no user-visible transactions. 2. Some ORM write operations are wrapped in transaction (unless already in transaction). Again, this is not user visible. Reason is that for example multitable save() should be atomic. That is, in 1.6 the mode is autocommit with some extra protection for certain ORM write operations. Another significant change: In pre 1.6 you can enter transaction block by @commit_on_success. All queries inside the block will be part of the same transaction. The name should be treated literally. If you nest commit_on_success decorators you might get surprising behavior: with commit_on_success: # Starts a transaction with commit_on_success: # Uses the same transaction obj.save() # Second commit_on_success commits on success. Note however that the first commit_on_success started the transaction. otherobj.save() raise Exception("what happens?") End situation is that obj.save() was committed, otherobj.save() wasn't. A new transaction was started after the inner commit_on_success block exited. In 99% of cases this isn't what was wanted. In 1.6 the code should be converted to: with atomic: # Starts a transaction with atomic: # Creates a savepoint obj.save() # The savepoint is released otherobj.save() raise Exception Now, the exception will cause a rollback of the transaction. Both obj and otherobj save are rolled back. All in all 1.6 transactions should be a lot easier to understand (there isn't one unless you explicitly asked for a transaction), and the atomic decorator is more powerful than commit_on_success. I am not sure if you will need some form of commit in 1.6 before the .get(). It depends on how the code is structured, and what does start the problematic transaction. If the code uses some form of explicit transaction control (commit_on_success, commit_manually) then the autocommit behavior will not be in effect, and you will need manual commit. If autocommit mode is in effect, things should just work. - Anssi -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at http://groups.google.com/group/django-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.