简体   繁体   中英

nested @commit_on_success in @commit_manually

I use the following utility function in several scripts:

@transaction.commit_on_success
def save_something(arg):
    # creation of a model_instance using arg
    model_instance.save()

In one of the scripts I upload lots of these model isntances to the database. In order to make this efficient I try to do:

@transaction.commit_manually
def save_many(arg_list):
    for i,arg in enumerate(arg_list):
        save_something(arg)
        if i%1000==0:
            transaction.commit()

Does the commit_manually override the commit_on_success ?
If not, how can I make it?

看看这个片段,我认为它以更好的方式处理嵌套的提交http://djangosnippets.org/snippets/1343/

The short answer is "No", and "you can't". What the decorators (and all they can really do) is wrap the functions they decorate in another function that starts a transaction if necessary, and then calls the original function. That's all the commit_manually decorator's wrapper function does. The commit_on_success decorator adds an automatic commit or rollback depending on the success of the wrapped function. The decorators aren't "runtime flags" that get toggled and that other behaviour then keys off of. They're simply a little boilerplate that gets wrapped around your function, and the commit_on_success decorator's boilerplate will always either commit or rollback.

The source for the decorators can tell you more about the details at hand: https://code.djangoproject.com/svn/django/trunk/django/db/transaction.py

You can:

@transaction.commit_on_success
def save_something(arg):
    _save_something(arg)

def _save_something(arg):
    # creation of a model_instance using arg
    model_instance.save()

and then in that single case where you do need it decorator free, use _save_something() ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM