【问题标题】:Would using transactions in a Celery task in Django application cause problems?在 Django 应用程序的 Celery 任务中使用事务会导致问题吗?
【发布时间】:2012-10-08 20:39:53
【问题描述】:

我写了一组芹菜任务。这些任务中的每一个都以作者 ID 作为参数(仅作为示例),并为作者的每本书获取最新价格并将其存储在数据库中。

我想通过将 Django 的 @transaction.commit_on_success 装饰器添加到我的任务中来将事务添加到我的任务中。如果任何任务崩溃,我希望整个任务都失败并且没有任何内容保存到数据库中。

我有十几个 celery 工人为作者检查书籍价格,我想知道这个简单的事务逻辑是否会在我的 Postgres 数据库中导致锁定和竞争条件。

我已经挖掘并发现了这个名为 django-celery-transactions 的项目,但我仍然不了解这背后的真正问题以及该项目试图解决的问题。

【问题讨论】:

    标签: python django transactions celery django-celery


    【解决方案1】:

    原因是,在您的 Django 视图中,如果您应用装饰器,则在视图退出之前不会提交数据库事务。在视图返回并触发提交之前,您可以调用期望 DB 事务已经提交的任务,即这些条目存在于 DB 上下文中。

    为了防止这种竞争条件(任务在您的视图之前开始并因此事务完成)您可以手动管理它或使用您提到的自动为您处理它的模块。

    例如,在您的情况下,它可能会失败的示例是,如果您要添加新作者,并且您有一个任务来获取其所有/任何书籍的价格。如果任务在新作者事务的提交完成之前执行,您的任务将尝试使用尚不存在的 id 获取作者。

    【讨论】:

      【解决方案2】:

      这取决于几个因素,包括:数据库的事务隔离级别、您检查价格更新的频率以及您预计价格变化的频率。例如,如果您每秒对stock standard PostgreSQL 进行大量更新,您可能会在事务中多次执行相同的选择语句得到不同的结果。

      数据库已针对并发处理进行了优化,因此我认为这对您来说不是问题;特别是如果您在获取价格后才打开交易(即使用上下文管理器而不是装饰任务)。如果 - 由于某种原因 - 未来事情变得缓慢,然后进行优化(不那么频繁地获取价格,调整数据库配置等)。

      至于您的其他问题:django-celery-transactions 旨在防止 Django 和 Celery 之间的竞争条件。一个示例是,如果您要将新创建的对象的主键传递给任务:该任务可能会在视图的事务提交之前尝试检索该对象。轰隆隆!

      【讨论】:

        猜你喜欢
        • 2015-04-22
        • 2012-09-06
        • 2012-08-09
        • 1970-01-01
        • 2017-05-15
        • 2017-02-02
        • 1970-01-01
        • 2016-09-23
        • 2011-06-19
        相关资源
        最近更新 更多