Django 嵌套事务和异常



为简单起见,我的代码中有一个嵌套的原子事务,基本上如果将人员添加到电影中失败(首先参见循环(,我想显示一个异常,特别是说明此操作失败并回滚movie.save(),工作室也是如此(参见第二个循环(。但是由于某种原因,当任何一个失败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块因异常退出时,会发生回滚。但是,您正在捕获异常并抑制它们,因此不会发生回滚。要让异常在记录消息后传播,您需要使用raise,而不是continue

最新更新