В моем приложении Django есть код, который удаляет один экземпляр модели из базы данных. Существует вероятность того, что два одновременных запроса могут попытаться удалить одну и ту же модель одновременно. В этом случае я хочу, чтобы один запрос был успешным, а другой - неудачным. Как я могу это сделать?
Проблема в том, что при удалении экземпляра с delete()
Django не возвращает никакой информации о том, была ли команда успешной или нет. Этот код иллюстрирует проблему:
b0 = Book.objects.get(id=1)
b1 = Book.objects.get(id=1)
b0.delete()
b1.delete()
Только одна из этих двух delete()
команд фактически удалила объект, но я не знаю, какая именно. Не выдается никаких исключений, и ничего не возвращается, чтобы указать на успешное выполнение команды. В чистом SQL команда вернула бы количество удаленных строк, и если бы значение было 0, я бы знал, что мое удаление не удалось.
Я использую PostgreSQL со стандартным уровнем изоляции Read Commited. Насколько я понимаю, этот уровень заключается в том, что каждая команда (SELECT, DELETE и т. Д.) Видит снимок базы данных, но следующая команда может видеть другой снимок базы данных. Я считаю, что это означает, что я не могу сделать что-то вроде этого:
# I believe this wont work
@commit_on_success
def view(request):
try:
book = Book.objects.get(id=1)
# Possibility that the instance is deleted by the other request
# before we get to the next delete()
book.delete()
except ObjectDoesntExist:
# Already been deleted
Есть идеи?