По умолчанию Django работает с открытой транзакцией, которую он фиксирует автоматически при вызове любой встроенной функции, изменяющей данные.В случае декораторов commit_on_success или commit_manually django фиксирует не после save (), а при успешном завершении выполнения функции или при выполнении командыaction.commit () соответственно.
Следовательно, элегантный подход заключается в разделенииКод обработки транзакций и другой трудоемкий код, если это возможно:
from django.db import transaction
from my_app.models import MyModel
@transaction.commit_on_success
def do_transaction(instances_to_save):
for inst in instances_to_save:
inst.save()
def model_altering_method():
instances_to_save = []
for inst in MyModel.objects.all()[0:5000]:
inst.name = 'Joel Spolsky'
# Some models independent time consuming operations...
instances_to_save.append(inst)
do_transaction(instances_to_save)
Если это невозможно с точки зрения дизайна, например, вам нужна информация instance.id, которую для новых экземпляров вы можете получить только после первого save (),попробуйте разбить поток на рабочие блоки разумного размера, чтобы не оставлять транзакцию открытой в течение долгих минут.
Также обратите внимание, что иметь длинные транзакции не всегда плохо.Если ваше приложение является единственной сущностью, изменяющей базу данных, это может быть действительно нормально.Однако вам следует проверить конкретную конфигурацию вашей базы данных, чтобы увидеть ограничение по времени для транзакций (или незанятых транзакций).