“transaction.atomic”与“transaction.commit_on_success”相同吗?

Django 1.6build议@transaction.atomic作为从1.5开始的事务pipe理中的一部分。

我有一个由Djangopipe理命令调用的函数,该命令又被cron调用,即在这种情况下,没有HTTP请求触发事务。 片段:

 from django.db import transaction @transaction.commit_on_success def my_function(): # code here 

在上面的代码块中, commit_on_successmy_function完成的所有工作使用单个事务。

@transaction.commit_on_successreplace@transaction.commit_on_success是否导致相同的行为? @transaction.atomic 文档状态 :

primefaces性是数据库事务的定义性质。 primefaces允许我们创build一个代码块,在这个代码块中保证数据库的primefaces性。 如果代码块成功完成,则更改将提交到数据库。 如果有exception,则更改将回滚。

我认为他们导致了同样的行为。 正确?

是。 你应该在之前使用commit_on_success的地方使用atomic

由于新的交易系统被devise为更健壮和一致,但是,您可能会看到不同的行为。 例如,如果您捕获数据库错误并尝试继续,您将看到一个TransactionManagementError ,而以前的行为是未定义的,可能与案例有关。

但是,如果你正在做的事情,一切都应该继续以同样的方式工作。

根据我已阅读的主题,这些装饰器嵌套时有显着的差异。

嵌套两个atomic块不能像嵌套两个commit_on_success块一样工作。

问题在于,您希望从这些块中获得两个保证。

  • 你希望块的内容是primefaces的,块内的所有内容都被提交,或者没有提交。
  • 你会喜欢耐久性,一旦你离开块没有例外,你保证,你写在块内的一切都是持久的。

块嵌套时不可能提供这两种保证。 如果在离开最内层块之后但在离开最外层块之前引发exception,则必须通过以下两种方式之一进行失败:

  • 无法为最内层的块提供耐久性。
  • 未能为最外面的块提供primefaces性。

这里是你find差异的地方。 使用commit_on_success会为最内层的块提供持久性,但是最外层的块没有primefaces性。 使用atomic会给最外层的块提供primefaces性,但对最内层的块没有耐久性。

在嵌套的情况下简单地引发exception可以防止您遇到问题。 最里面的块总是会引发exception,因此它永远不会承诺任何耐久性。 但是这失去了一些灵活性。

一个更好的解决scheme将是有更多的粒度你所要求的。 如果你可以单独要求primefaces性和耐久性,那么你可以执行嵌套。 您只需确保每个请求持久性的块都在请求primefaces性之外。 在请求primefaces性的块内请求持久性将不得不引发exception。

atomic应该提供primefaces性的一部分。 据我所知,django 1.6.1没有装饰器,可以要求耐久性。 我试图写一个,并将其发布在codereview上。