Стоит ли мне использовать `select_for_update` в моем приложении для транскрипции на Django?
Мое приложение позволяет пользователям загружать и расшифровывать аудиофайлы. Мой код хранит аудиофайл и расшифровку в базе данных postgres.
Вот мой оригинальный код:
try:
transcribed_doc = TranscribedDocument.objects.get(id=session_id)
except TranscribedDocument.DoesNotExist:
...
try:
if transcribed_doc.state == 'not_started':
transcribed_doc.state = 'in_progress'
transcribed_doc.save()
...
Вот скорректированный код:
try:
transcribed_doc = TranscribedDocument.objects.select_for_update().get(id=session_id)
except TranscribedDocument.DoesNotExist:
...
try:
if transcribed_doc.state == 'not_started':
transcribed_doc.state = 'in_progress'
transcribed_doc.save()
...
Я знаю, что select_for_update()
используется для блокировки обновляемой строки, чтобы предотвратить ситуации, когда несколько вызовов могут попытаться обновить одну и ту же запись одновременно. Но я могу представить себе такую ситуацию, если один и тот же пользователь по ошибке или злонамеренно запустит один и тот же процесс транскрипции несколько раз, например, нажав несколько раз кнопку "начать транскрипцию".
Если вы предполагаете, что данные могут обновляться параллельными запросами, лучше всегда блокировать строки. Хотя в настоящее время у вас может быть не так много примеров, когда строки обновляются одновременно, с ростом приложения таких ситуаций может стать больше. Например, вы можете добавить фоновый процесс, который проверяет что-то и обновляет поле в модели.
Однако если вы не предполагаете, что это произойдет, можно обойтись пока без блокировок и добавить их позже, когда возникнет необходимость. В конце концов, все зависит от количества запросов/пользователей, которые используют ваше приложение.
Также читайте о deadlocks
и о том, почему они происходят.