Also, thank you Tom, Christian, Christophe, and Anssi for helping me track 
down this problem. Users are now receiving notifications in a timely manner 
because of you.

On Tuesday, May 28, 2013 6:07:22 PM UTC-4, Chris Conover 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...
>
> On Tuesday, May 28, 2013 5:43:31 PM UTC-4, Chris Conover wrote:
>>
>> I bribed the DBA to turn on the general query log briefly (which 
>> generated 327k logs in 2 minutes and 2 seconds). Looking at the logs, I see 
>> the transaction block for the INSERT. The SELECT is definitely coming after 
>> the COMMIT in a different thread. I'll try the commit_unless_managed fix 
>> quickly and if that doesn't work, I'll post the full query trace.
>>
>> On Tuesday, May 28, 2013 5:27:36 PM UTC-4, akaariai wrote:
>>>
>>> On 28 touko, 22:20, Chris Conover <[email protected]> wrote: 
>>> > Well, you can inspect the object and see it's primary key. Surely that 
>>> > means the INSERT is completed? So the workflow goes like this: 
>>> > 
>>> > foo = Foo() 
>>> > foo.save() 
>>> > foo.pk # new primary key is available 
>>> > submit_gearman_task(foo.pk) 
>>> > 
>>> > Then in the Gearman worker: 
>>> > 
>>> > foo = Foo.objects.get(pk=foo_pk) # this causes a Foo.DoesNotExist 
>>> exception 
>>> > 
>>> > That's what I don't understand. The primary key is assigned and 
>>> available 
>>> > in the application layer in one place but then the lookup using that 
>>> > primary key fails in another place. Maybe it has something to do with 
>>> the 
>>> > fact that the database is set to REPEATABLE-READ isolation level 
>>> versus 
>>> > READ-COMMITTED. Still investigating... 
>>>
>>> Could it be that the Gearman worker is in a transaction? When you 
>>> issue Foo.objects.get(), if the transaction Gearman is in has started 
>>> before the save() you will not see the new object (as MySQL uses 
>>> REPEATABLE READ transaction). 
>>>
>>> Note that any read query will start a transaction implicitly, and ORM 
>>> writes commit implicitly started transaction. You can also use 
>>> connection.commit_unless_managed() to commit implicitly started 
>>> transaction (not part of public API!). So, even if you haven't 
>>> explicitly started any transactions in Gearman worker an earlier read 
>>> query might have started one for you. (If you find this behavior 
>>> confusing this is one of the reasons why transaction handling will be 
>>> changed in Django 1.6). 
>>>
>>> In short: try if connection.commit_unless_managed() before the get() 
>>> changes anything. If so, investigate why there is an ongoing 
>>> transaction in the worker. 
>>>
>>>  - 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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to