在与数据库交互时django中的多线程,我需要知道并注意什么?

时间:2016-06-06 16:07:22

标签: python django database multithreading django-celery

我的网站需要定期解析来自多个网页的大量数据。我正在考虑使用芹菜或python线程加快速度。

我害怕在与数据库交互时难以调试错误。 例如,当2个线程同时调用SampleModel.object.get_or_create(name="same string")时,可能会发生什么? 或者如果(简化伪代码显示想法)会发生什么:

mymodel(models.Model)
      title = models.CharField()
      (...)
      owner = models.ManyToManyField(Creator)

def FindPageCreatorName(page):
    (...)
    return name

在多个线程中我将调用

def create_mymodel(url): #thats what will be run in each thread
    page = urllib.urlopen(url)
    mymodelInstance.title = FindPageTitle(page)
    (...)
    mymodelInstance.save()
    creator = Creator.get_or_create(name=FindPageCreatorName(page))
    mymodelInstance.creator.add(creator)

它会在大致相同的时间内在多个页面上找到相同的创建者名称? (其他线程将在另一个指令之间更改数据库)

我应该在事务中封装每个线程吗,这足以防止错误吗?

哪些其他方案可能无法正常工作? 或者我不应该担心,因为没有什么不好的事情可以发生,芹菜会照顾这些东西吗?

如果你不能指出我有关这个主题的任何好的教程或文档,我将不胜感激。对于这样模糊的问题,我很抱歉,但我不知道可能会出现哪些具体问题 - 这就是问题所在。 此外,代码中可能只需要多线程 - 在这种情况下我应该使用celery还是python线程? (不是过度杀戮吗?)

1 个答案:

答案 0 :(得分:1)

如果每秒有足够的请求,肯定会发生不好的事情。

如果两个线程同时调用SampleModel.object.get_or_create(name="same string")会发生什么?如果有两个流程呢?如果两个工作节点调用它会怎么样?

在这种情况下,您需要考虑可能发生故障的位置。

如果有两个工作节点接受来自Celery的作业,并且两个工作节点同时调用数据库操作,则django代码库中没有任何内容可以保证将会发生什么。

如果同一进程中的两个不同线程调用数据库操作,则它们无法同时调用它,因为它们受CPU访问限制。

但是如果你有多个节点,谁击中了数据库,数据库本身会一个接一个地执行它们(有例外)。因此,在这种情况下,您需要确保数据库拒绝第二个create命令。根据数据库的不同,可以通过在相关字段上添加唯一索引来完成。

您需要考虑您的设计,并确保在数据库中有顺序数据写入(如果这是您需要的)。在某些数据库中,并行数据写入将提供更好的性能,但不会提供数据完整性。