У меня есть класс модели с именем DataObj и некоторый метод copmlex, который вначале извлекает экземпляр DataObj, выполняет некоторые вычисления и обновляет его поля.
Для обеспечения целостности в параллельной среде мое приложение использует оптимистическую блокировку c с использованием целых чисел поле версии.
Чтобы не обернуть все вычисления в @ atomi c, у меня есть короткая и быстрая функция save_changes:
@transaction.atomic
def save_changes(DataObj dataObj):
db_instance = DataObj.objects.select_for_update().get(id=dataObj.id, version=dataObj.version)
# copy all changes from dataObj to db_instance
db_instance.save()
, и я вызываю ее из моего сложного метода
def long_update_func(dataobj_id):
obj = DataObj.objects.get(id=dataobj_id)
# perform several calculations, update fields
obj.field1 = result_of_calc1()
...
try:
save_changes(obj)
except:
# whoops, version changed
notify_data_changed_during_calculations()
Вопрос : копирование полей действительно раздражает. Можно ли избежать копирования полей в функции save_changes? У меня есть хороший измененный dataObj с точно таким же идентификатором, который я использую для блокировки строк базы данных в вызове select_for_update.
Могу ли я просто переписать так (или аналогично):
@transaction.atomic
def save_changes(DataObj dataObj):
db_instance = DataObj.objects.select_for_update().get(id=dataObj.id, version=dataObj.version)
# save our dataObj, because it has same id as db_instance and therefore its row in db table is locked
dataObj.save()
?