On Wed, Aug 8, 2012 at 9:25 AM, Cal Leeming [Simplicity Media Ltd] < [email protected]> wrote:
> I'm not entirely sure that suggesting every query needs to be committed is > the right way forward either, given that you only need to commit once > before get_or_create() is called to prevent the issue. > > Could you expand on why you feel every query would need to be committed? > get_or_create does: 1 - get 2 - if get fails due to DoesNotExist, create 3 - if create fails due to IntegrityError, get again The problem with repeatable read transaction level is that step 3 can never return something other than what was found (or not) in step 1. If some other thread, between the times at which 1 and 2 happen, creates what this thread is attempting to get_or_create, then the get_or_create is going to fail, because the get will still find nothing in step 3, causing get_or_create to re-raise the IntegrityError from step 2. Issuing a commit before calling get_or_create doesn't fix this race condition that exists within the get_or_create code itself. Such a pre-call commit is only going to be helpful if the current transaction has already done a read that has fixed what is going to be returned by the DB in step 1. If that has happened, then committing before calling get_or_create will reduce the likelihood of hitting the race condition, since step 1 may then read a row that has been created subsequent to the last read by this thread but before this thread gets to step 1 in get_or_create. Essentially the pre-commit narrows the race condition window in this case. (If no read has yet been done by the transaction to already set in stone what this transaction will read in step 1, then committing before calling get_or_create does not help at all.) Regardless of what's done before the call into get_or_create, there's still a small window of opportunity, between steps 1 and 2, for get_or_create to fail. get_or_create requires either DB level autocommit or read committed transaction isolation level in order for it to be free of this race condition. Recommending anything else in Django's docs would be misleading. Karen -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
