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

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

问题描述

由于django模型save()方法不懒,保持事务短是一个一般的良好做法,应该保存优选延迟到事务块的结束吗?



例如,代码示例B是否保持事务开放

代码示例A:

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

@ transaction.commit_on_success
def model_altering_method():
for in in MyModel.objects.all ()[0:5000]:
inst.name ='Joel Spolsky'
#一些模型独立耗时操作...
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 = []
inst in MyModel.objects.all()[0:5000]:
inst.name ='Joel Spolsky'
#一些模型独立耗时操作...
instances_to_save.append )

for inst in instances_to_save:
inst.save()




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

 来自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 MyModel.objects.all()[0:5000]:
inst.name = Joel Spolsky'
#一些模型独立耗时操作...
instances_to_save.append(inst)
do_transaction(instances_to_save)

如果这是不可能的设计明智的,例如你需要instance.id信息,对于新的实例你只能在第一次save()之后才能获得,尝试将你的流分解到合理大小的工作单元,而不是保持事务打开很长时间。



也注意到,长交易并不总是一件坏事。如果你的应用程序是修改db的唯一实体,它实际上可以确定。但是,您应该检查数据库的具体配置,以查看事务(或空闲事务)的时间限制。


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?

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

Code sample 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()

Code sample 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’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)

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.

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天全站免登陆