Django - 保存基于save()的事务 [英] Django - Keeping save() based transactions short

查看:339
本文介绍了Django - 保存基于save()的事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于django模式save()方法不懒惰,而且保持交易简短是一般的良好做法,应该将保存优先推迟到交易块的结尾?

As django model save() methods are not lazy, and as keeping transactions short is a general good practice, should saves be preferably deferred to the end of transaction blocks?

作为示例,代码示例B是否为少于下面代码样本A的时间?

As an example, would the code sample B hold a transaction open for less time than code sample A below?

代码示例A:

from django.db import transaction
from my_app.models import MyModel

@transaction.commit_on_success
def model_altering_method():
    for inst in MyModel.objects.all()[0:5000]:
        inst.name = 'Joel Spolsky'
        # Some models independent time consuming operations...
        inst.save()

代码示例B:

from django.db import transaction
from my_app.models import MyModel

@transaction.commit_on_success
def model_altering_method():
    instances_to_save = []
    for inst in MyModel.objects.all()[0:5000]:
        inst.name = 'Joel Spolsky'
        # Some models independent time consuming operations...
        instances_to_save.append(inst)

    for inst in instances_to_save:
        inst.save()


推荐答案

Django的默认行为是运行一个开放的事务,它在任何内置的数据时自动提交调用模型函数。在commit_on_success或commit_manually装饰器的情况下,django不会在save()上执行,而是分别执行成功完成功能或在transaction.commit()命令上执行。

Django’s default behavior is to run with an open transaction which it commits automatically when any built-in, data-altering model function is called. In case of commit_on_success or commit_manually decorators, django does not commit upon save(), but rather on function execution successful completion or on transaction.commit() command respectively.

因此,优雅的方法是将事务处理代码和其他耗时的代码分开,如果可能的话:

Therefore, the elegant approach would be to separate the transaction handling code and other time consuming code if possible:

from django.db import transaction
from my_app.models import MyModel

@transaction.commit_on_success
def do_transaction(instances_to_save):
    for inst in instances_to_save:
        inst.save()

def model_altering_method():
    instances_to_save = []
    for inst in MyModel.objects.all()[0:5000]:
        inst.name = 'Joel Spolsky'
        # Some models independent time consuming operations...
        instances_to_save.append(inst)
    do_transaction(instances_to_save)

如果这是不可能的设计明智的,例如您需要使用instance.id信息,对于新实例,只能在第一个save()之后才能获得,尝试将流量分解为合理大小的工作单元,以免长时间保持事务处理。

If this is impossible design wise, e.g. you need instance.id information which for new instances you can only get only after the first save(), try breaking up your flow to reasonably sized workunits, as not to keep the transaction open for long minutes.

另请注意,长时间的事务并不总是坏事。如果您的应用程序是修改db的唯一实体,那么它实际上可以。然而,您应该检查数据库的具体配置,以查看事务(或空闲事务)的时间限制。

Also notice that having long transactions is not always a bad thing. If your application is the only entity modifying the db, it could actually be ok. You should however check the specific configuration of your db to see the time limit for transactions (or idle transaction).

这篇关于Django - 保存基于save()的事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆