在Django中使用带有错误处理的原子块

在Django中使用带有错误处理的原子块,django,database,transactions,rollback,Django,Database,Transactions,Rollback,我有一个Django 1.9应用程序,它运行一段代码,根据对某些远程API的查询结果对数据库进行更改。例如,这可能是有关提交、文件更改、审阅者、拉取请求等的数据,我希望将这些数据保存为数据库中的实体 commit_data = commit_API_client.get_commit_info(argument1, argument2) new_commit = models.Commit.Create(**commit_data) #if the last API failed, this

我有一个Django 1.9应用程序,它运行一段代码,根据对某些远程API的查询结果对数据库进行更改。例如,这可能是有关提交、文件更改、审阅者、拉取请求等的数据,我希望将这些数据保存为数据库中的实体

commit_data = commit_API_client.get_commit_info(argument1, argument2)
new_commit = models.Commit.Create(**commit_data)

#if the last API failed, this will fail
#I will need to run this again to get these files, so I need
#to get the commit all over again, too
files = file_API_client.get_file_info(new_commit.id)
new_files = models.Files.Create(**files)

#do some more stuff here 
我正在调用的几个API中的一个很可能会返回一些错误,而不是有效数据。我基本上需要将此部分转换为单个原子事务,这样,如果
HTTP请求
没有返回错误,我就将所有更改提交到数据库。否则,如果2个API返回正确,我可能会丢失一些数据,但第3个API没有


我看到Django支持数据库事务的
commit hooks
,但我想知道这是否适用于这种情况,以及我将如何实现它。

如果您想将其变成一个原子操作,只需将其打包。如果您的任何代码引发异常,整个块将回滚。如果您只是从远程API进行读取,那么应该可以正常工作。典型的模式是:

def my_function():
    try:
        with transaction.atomic():
            # Do your work here
            pass
    except Exception:
        # Do some error handling
        pass

Django确实有一个,但这在这里并不适用。它的目的是在事务成功完成后运行一些代码。例如,如果事务成功,您可以使用它将一些日志数据写入远程API。

在异常情况下,
transaction.atomic()
是否正常退出?这都是围绕错误处理而设计的,因此当出现错误时,我需要
排除异常,并记录错误,向某些用户报告,等等。或者我必须从另一个函数调用我的函数,该函数执行
尝试除外
块并从那里执行错误处理吗?@skeletalbassman:当然,您只需将原子块包装在try-except子句中。我在答案中添加了一个例子。是的,这就成功了。我已经修改了您的示例,可以验证它是否有效。