【问题标题】:What is the correct place to use the @transaction.atomic decorator?使用 @transaction.atomic 装饰器的正确位置是什么?
【发布时间】:2018-02-11 12:01:56
【问题描述】:

在我的 Django 应用程序中,我想包装在事务中的第一个数据库操作可能发生在框架的任何级别——它可能在视图、管理器方法或模型方法中。

到目前为止,我的做法是用@transaction.atomic 标记第一次发生数据库写访问的最外层方法。但我发现跟踪这件事很痛苦。当我重构或移动东西时,最外层的方法经常改变。处理这个问题的最佳方法是什么?

以下是我正在考虑的一些选项,当然我愿意接受任何其他建议。

选项 1:仅查看方法。

我是否应该总是在视图级别声明 @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

选项 2:所有方法。

或者我应该包装导致多个数据库操作的每个方法?

@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

选项 3:只有我期望的方法会被外部调用。

或者我应该只在属于应用程序外部 API 的方法上声明 @transaction.atomic?例如,在这里,我希望 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

这个选项似乎是最“正确”的......但它使我的问题永久化。当我重构和重写应用程序时,外部 API 可能会发生变化,这也迫使我猜测应用程序将来会如何使用,我目前可能还不知道。

处理这个问题的标准方法是什么?

【问题讨论】:

标签: django transactions


【解决方案1】:

一般规则是包装最外层的函数/方法,对于 Django,它必须是控制器函数/方法。

但是,根据您的业务逻辑,您可以拥有嵌套的保存点(每个嵌套的 transaction.atomic 只是创建保存点),您希望在其中更精细地控制提交或回滚的内容。在这种情况下,任何其他内部函数都可以用 transaction.atomic 包装。

另外,不推荐使用ATOMIC_REQUESTS(这里解释在Django Docs

【讨论】:

    猜你喜欢
    • 2011-12-15
    • 2014-06-08
    • 1970-01-01
    • 2016-07-19
    • 2016-11-25
    • 1970-01-01
    • 2015-01-04
    • 2021-05-30
    相关资源
    最近更新 更多