mysql 如果Django ORM中同时发生两个DML,如何确保数据正确?

lztngnrs  于 2023-04-10  发布在  Mysql
关注(0)|答案(1)|浏览(125)

我在我的Django项目中使用mysqlInnoDB引擎。

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

我有两个过程,一个是根据表中的最大队列插入一条记录。

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)

另一个过程是将queue不等于0的每条记录的queue的值减1

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)

这里我关心的是,如果两个进程同时发生。例如,如果后面的进程要减少每个值,而同时,第一个进程插入一个新值。在这种情况下,就会出现一些错误。
我该怎么做呢?谁有好主意,提前谢谢。

nx7onnlm

nx7onnlm1#

您可以使用select_for_update()来实现此目的,它将锁定您正在更新的记录,直到事务结束

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

相关问题