想象一下,您的网络应用中有User
模型,您需要通过API让该用户与外部服务保持同步。因此,当您在本地创建用户时,您还需要远程创建它。
您已完成transaction.atomic()
下的所有操作,并尝试在原子块之后保留所有第三方API调用,这是合理的。
但是,作为一个系统的系统,它会变得复杂,直到你有一些非常难以在更新调用中删除第三方调用的那一点。
那说,有没有办法扩展Django的事务机制,有点像添加一些回调函数,比如rollback.add_callback(clean_3rdparty_user(user_id=134))
?
这样我可以保证采取所有必要的回滚操作并且我的系统是同步的吗?
答案 0 :(得分:2)
Django的交易钩子代码的作者this to say关于为什么有on_commit()
而不是on_rollback()
:
回滚挂钩比提交挂钩更难实现,因为各种各样的东西都可能导致隐式回滚。例如,您的数据库连接被删除,因为您的进程被杀死而没有机会正常关闭:您的回滚挂钩永远不会运行。
由于回滚通常由异常触发,因此一种简单的方法是捕获任何异常并在那里运行撤消代码。
try:
with transaction.atomic():
# Do database stuff
# Do external stuff
except:
# We know the database stuff has rolled back, so...
# Undo external stuff
raise
这不是特别优雅。我同意以下来自同一来源:
解决方案很简单:在原子块(事务)期间执行某些操作,然后在事务失败时撤消它,使用on_commit在事务成功之前首先延迟执行它。撤消一下你从未做过的事情要容易得多!
但听起来你也同意这一点。