Повторяющиеся потоки запросов создают дублированные записи базы данных в модели Django - PullRequest
2 голосов
/ 12 марта 2011

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

В функции приемника:

try:
    my_instance = MyModel.objects.get(field1=value1, field2=sender)
except:
    my_instance = MyModel(field1=value1, field2=sender)
    my_instance.save()

Это очевидный кандидат на get_or_create, но кроме очистки этого кода, поможет ли get_or_create предотвратить эту проблему?

Сигнал отправляется после действия пользователя, но я не верю, что исходный запрос дублируется, потому что это вызвало бы другие действия.

Дублирование происходило несколько раз в тысячах случаев.Обязательно ли это вызвано несколькими запросами или есть какой-то способ создать дублирующую нить?И есть ли способ - возможно, с гранулярным управлением транзакциями - предотвратить дублирование?

Использование Django 1.1, Python 2.4, PostgreSQL 8.1 и mod_wsgi на Apache2.

Ответы [ 2 ]

2 голосов
/ 12 марта 2011

для предотвращения дублирования сигналов добавьте параметр "dispatch_uid" к коду присоединения сигнала как , описанное в документации .

убедитесь, что у вас открыта транзакция - в противном случае может случиться так, что между check (objects.get ()) и cration (save ()) состояние таблицы изменится.

1 голос
/ 12 марта 2011

Возможно этот ответ может помочь.Очевидно, транзакция правильно используется с get_or_create, но я не подтвердил это.mod_wsgi является многопроцессорным и многопоточным (оба настраиваются), что означает, что условия гонки могут определенно возникнуть.Я предполагаю, что в вашем приложении происходит то, что запускаются два отдельных запроса, которые сгенерируют одно и то же значение для field1, и так получилось, что они выполняются с правильным временем, чтобы добавить «повторяющиеся» записи.

Если комбинация MyModel(field1=value1, field2=sender) должна быть уникальной, определите ограничение unique_together для вашей модели, чтобы еще больше повысить ее целостность.

...