当多线程对数据库进行访问和操作时,需要考虑到一些并发的问题。django针对此类问题给出了很多解决方案。在django体系中,将每一次的数据库访问称为一次transaction。于此同时,django对数据库的操作还提供了<model_name>.select_for_update().<function>的api。这个select_for_update能够调用数据库的api,对某些数据进行锁定,让并发的其他线程无法立刻访问。
总体上来说,做到多线程安全操作的关键在于2个点,第一,锁定django的transaction防止django内部的多线程互相干涉。第二,锁定数据库的访问,防止多个服务器对数据库的操作互相干涉。
具体操作方法如下:
为Model增加类函数。之所以是类函数,是因为成员函数的本身能够访问时,就已经从数据库提取过数据了。
from django.db import models, transaction
#... in model class...
@classmethod
def getPendingTask(cls):
with transaction.atomic():
try:
pendings = cls.objects.select_for_update().filter(status = TaskStatus.PENDING)
if len(pendings) < 1:
return False
first = pendings[0]
first.convert_start_date = timezone.now()
first.status = TaskStatus.CONVERTING
first.save()
return {
'name': first.name,
'filename': first.filename
}
except Exception as e:
return False