我有一个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 requests
返回错误,我会将所有更改提交到数据库。否则,如果2个API正确返回,我可能会丢失一些数据,但第3个没有。
我看到Django支持commit hooks
进行数据库事务,但我想知道这是否适用于这种情况以及我将如何实现它。
答案 0 :(得分:4)
如果要将其转换为原子操作,只需将其包装在transaction.atomic()
中即可。如果您的任何代码引发异常,则整个块将回滚。如果您只是从远程API读取应该正常工作。典型的模式是:
def my_function():
try:
with transaction.atomic():
# Do your work here
pass
except Exception:
# Do some error handling
pass
Django确实有on_commit
hook,但这并不适用于此。其目的是在事务成功完成后运行一些代码。例如,如果事务成功,您可以使用它将一些日志数据写入远程API。