为了简单起见,我的代码中有一个嵌套的原子事务,基本上,如果将人员添加到电影失败(请参阅第一个 for 循环),我想显示一个异常,专门说明此操作失败并回滚 movie.save()
,与工作室相同(请参阅第二个 for 循环)。但由于某种原因,当其中任何一个失败 movie.save()
都不会回滚时,我会在数据库中保存一部电影,而没有任何人员或工作室附加到它。
people = ['Mark', 'John', 'Mark']
studios = ['Universal Studios', 'Longcross Studios']
try:
with transaction.atomic():
movie = Movie(title=title, description=summary, pub_date=pub_date)
movie.save()
# iterate through people list, get the pk from database and add it to the movie
try:
with transaction.atomic():
for p in people:
person = Person.objects.get(name=p)
movie.people.add(person)
except Person.DoesNotExist:
self.stdout.write(self.style.ERROR('One or more performers from %s does not '
'exist in database, please add them and '
'rerun the command.' % str(people)))
continue
# iterate through studio list, get the pk from database and add it to the movie
try:
with transaction.atomic():
for s in studios:
studio = Studio.objects.get(name=s)
movie.studios.add(studio)
except Studio.DoesNotExist:
self.stdout.write(self.style.ERROR('One or more studios from %s does not '
'exist in database, please add them and '
'rerun the command.' % str(studios)))
continue
movie.save()
self.stdout.write(self.style.NOTICE('Successfully added movie %s' % title))
except Exception as e:
self.stdout.write(self.style.ERROR('Failed to add movie to the database.'))
最佳答案
当atomic
block 因异常退出时会发生回滚。但是您正在捕获异常并抑制它们,因此回滚不会发生。要让异常在记录消息后传播,您需要使用 raise
,而不是 continue
。
关于python - Django 嵌套事务和异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62116750/