правильный способ поймать состояние гонки с Django ORM + MySQL / InnoDB - PullRequest
1 голос
/ 21 июля 2010

Одна часть моего приложения имеет состояние состязания, когда несколько потоков могут создать один и тот же постоянный объект. Итак, я реализовал код, который выглядит следующим образом:

from foobar.models import Bar

def testomatic(request):
    bar = None
    tries = 0
    while not bar:
        try:
            bar = Bar.objects.get(b=2)

        except Bar.DoesNotExist:
            time.sleep(10) # put in here to force the race condition
            bar = Bar(a = 2, b = 2)
            try:
                bar.save()
            except IntegrityError:
                tries += 1
                bar = None

            if tries > 1:
               raise Exception("something bad happened")

    return HttpResponse("tries = %s" % tries)

И это работает нормально в моей тестовой среде - но когда я запускаю это с "настоящими" классами, оно, кажется, вращается, постоянно получая ничего от get (), но всегда получая IntegrityError в save (). 1004 *

Я использую MySQL / InnoDB в качестве движка базы данных. Есть ли что-то в обработке MVCC, которая мешает мне получить запись, но выдает ошибку двойного ключа при попытке ее создать?

1 Ответ

0 голосов
/ 22 июля 2010

Правильный способ сделать это - перейти на необработанный SQL, чтобы можно было заблокировать таблицу при первоначальном выполнении SELECT, а затем создать и сохранить объект, если он не существует, и разблокировать таблицу.

...