Comment s'assurer que les données sont correctes si deux DML se produisent simultanément dans Django ORM ?
P粉041881924
P粉041881924 2023-09-14 15:11:12
0
1
557

Mon Django 项目使用 mysqlInnoDB 引擎。我有一个如下所示的表,queue字段默认值为0

class Task(models.Model):
    task_id = models.CharField(max_length=32, primary_key=True)
    queue = models.IntegerField(default=0)

J'ai deux processus, l'un consiste à insérer un enregistrement basé sur la file d'attente maximale dans la table.

max_queue = Task.objects.all().annotate(data=Max('queue')).values('data')
 queue_number = max_queue[0]['data'] + 1
 record = {'task_id':task_id, 'queue': queue_number}
 Task.objects.create(**record)

Un autre processus consiste à soustraire 1queue不等于0的每条记录,将queue de la valeur de

query_list = Task.objects.filter(~Q(task_queue=0))
for query in query_list:
    Task.objects.filter(task_id=task_id).update(queue=query.queue - 1)

Ce qui m'importe ici, c'est si ces deux processus se produisent en même temps. Par exemple, si le processus suivant souhaite décrémenter chaque valeur. Dans le même temps, le premier processus insère une nouvelle valeur. Dans ce cas, certaines erreurs peuvent survenir.

Que dois-je faire ? Quelqu'un a-t-il une bonne idée, merci d'avance.

P粉041881924
P粉041881924

répondre à tous(1)
P粉557957970

Vous pouvez utiliser select_for_update() a> pour cela, cela verrouillera l'enregistrement que vous mettez à jour jusqu'à la fin de la transaction

from django.db import transaction
from django.db.models import Q

with transaction.atomic():
    query_list = Task.objects.select_for_update().filter(~Q(queue=0))
    for query in query_list:
        query.queue -= 1
        query.save()
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal