tin*_*ino 5 django transactions
在我的Django应用程序中,我要包装在事务中的第一个数据库操作可能发生在框架的任何级别上-可能在视图,管理器方法或模型方法中。
到目前为止,我的实践一直是用标记最先发生数据库写访问的最外层方法@transaction.atomic。但是我发现要跟踪它很痛苦。当我重构或移动事物时,最外面的方法经常更改。处理此问题的最佳方法是什么?
这是我正在考虑的一些选项,当然我可以接受其他建议。
我是否应该总是@transaction.atomic在视图级别声明并完成它?
@transaction.atomic
def view_method():
# database operation
manager_method()
def manager_method():
# database operation
model_method()
def model_method():
# database operation
another_model_method()
def another_model_method():
# database operation
Run Code Online (Sandbox Code Playgroud)
还是应该包装所有导致多种数据库操作的方法?
@transaction.atomic
def view_method():
# database operation
manager_method()
@transaction.atomic(savepoint=False)
def manager_method():
# database operation
model_method()
@transaction.atomic(savepoint=False)
def model_method():
# database operation
another_model_method()
def another_model_method():
# database operation
Run Code Online (Sandbox Code Playgroud)
还是应该@transaction.atomic只声明属于应用程序外部API一部分的方法?例如,在这里,我希望model_method()也可以从脚本或管理界面等调用它。
@transaction.atomic
def view_method():
# database operation
manager_method()
def manager_method():
# database operation
model_method()
@transaction.atomic(savepoint=False)
def model_method():
# database operation
another_model_method()
def another_model_method():
# database operation
Run Code Online (Sandbox Code Playgroud)
此选项似乎是最“正确的” ...但是它使我的问题永久存在。当我重构和重写应用程序时,外部API可能会发生变化,这也迫使我猜测将来可能如何使用该应用程序,这在这一点上我可能还不知道。
处理此问题的标准方法是什么?
通用规则是包装最外层的函数/方法,对于 Django,它必须是控制器函数/方法。
但是,根据您的业务逻辑,您可以拥有嵌套的保存点(每个嵌套transaction.atomic只是创建保存点),您希望在其中更精细地控制要提交或回滚的内容。在这种情况下,任何其他内部函数都可以用transaction.atomic.
另外,不建议使用 ATOMIC_REQUESTS (在Django Docs中有解释)