Jon*_*han 5 database django performance transactions django-models
由于django模型的save()方法并不是懒惰的,并且由于保持事务简短是一般的好习惯,应该保存优先级延迟到事务块的末尾?
例如,代码示例B是否会将事务打开的时间少于下面的代码示例A?
代码示例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()
Run Code Online (Sandbox Code Playgroud)
代码示例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()
Run Code Online (Sandbox Code Playgroud)
Django\xe2\x80\x99s 默认行为是使用打开的事务运行,当调用任何内置的数据更改模型函数时,它会自动提交。在 commit_on_success 或 commit_manually 装饰器的情况下,django 不会在 save() 上提交,而是在函数执行成功完成或 transaction.commit() 命令上分别提交。
\n\n因此,如果可能的话,优雅的方法是将事务处理代码和其他耗时的代码分开:
\n\nfrom django.db import transaction\nfrom my_app.models import MyModel\n\n@transaction.commit_on_success\ndef do_transaction(instances_to_save):\n for inst in instances_to_save:\n inst.save()\n\ndef model_altering_method():\n instances_to_save = []\n for inst in MyModel.objects.all()[0:5000]:\n inst.name = 'Joel Spolsky'\n # Some models independent time consuming operations...\n instances_to_save.append(inst)\n do_transaction(instances_to_save)\n
Run Code Online (Sandbox Code Playgroud)\n\n如果这在设计上是不可能的,例如您需要 instance.id 信息,对于新实例,您只能在第一次 save() 之后才能获得该信息,请尝试将流程分解为合理大小的工作单元,以免事务长时间保持打开状态。
\n\n另请注意,长时间交易并不总是坏事。如果您的应用程序是修改数据库的唯一实体,那么实际上可能没问题。但是,您应该检查数据库的具体配置,以查看事务(或空闲事务)的时间限制。
\n