commit_on_success如何处理嵌套?

Jua*_*aza 11 database django django-orm

我对如何处理特定情况下的交易感到有点困惑.

我有一些代码可以归结为:

from django.db import transaction

@transaction.commit_on_success
def process_post():
    #do stuff with database
    for reply in post_replies:
        process_post_reply(reply)

@transaction.commit_on_success
def process_post_reply(reply):
    #do stuff with database
Run Code Online (Sandbox Code Playgroud)

我想知道如果process_post_reply()失败会发生什么.

commit_on_success如何处理嵌套?是否理解提交每个process_post_reply()或如果一个失败整个process_post()回滚?

Tom*_*ski 11

这是它的源代码:https://github.com/django/django/blob/1.2.4/django/db/transaction.py#L286

enter_transaction_management就像在线程堆栈上放置新的事务处理模式一样简单.

因此,在您的情况下,如果process_post_reply()失败(即发生异常),则事务将完全回滚,然后异常向上传播,process_post()但没有任何内容可以回滚.

不,如果一个process_post_reply()失败,那么整个process_post()没有被回滚 - 那里没有魔法,只有数据库级别的COMMIT和ROLLBACK,这意味着回滚的内容只是在最后一次提交后写入数据库的内容process_post_reply().

总之,我认为你需要的仅仅是一个单一的commit_on_success()周围process_post,可能通过支持事务保存点 -仅在PostgreSQL后端不幸可用,即使MySQL的5.x的支持他们.

编辑2012年4月10日:Django 1.4现在提供对MySQL的Savepoint支持

编辑2014年7月2日:事务管理已在Django 1.6中完全重写 - https://docs.djangoproject.com/en/1.6/topics/db/transactions/commit_on_success已被弃用.