解决Django / postgres中的竞争条件

时间:2017-04-18 23:51:17

标签: django postgresql race-condition

我有一个发送付款收据的django视图,在多线程环境中,如果快速连续多次调用,此视图会多次发送收据。我执行更新的代码看起来像

updated = Transaction.objects \
    .filter(id=transaction_id, status='processing') \
    .update(status='paid')
if updated:
    # send email

我在互联网上阅读的所有内容都表明,选择和更新需要在一个查询中更新的行,就像我在这里所做的那样应该有效。我做错了什么?

我也试过

with transaction.atomic():
    trans = Transaction.objects.select_for_update() \
                       .get(id=transaction_id)
    if trans.status == 'processing':
        trans.status = 'paid'
        trans.save()
        updated = True
    else:
        updated = False

我尝试过的其他事情:

  • 在原始sql中执行所有操作,即cursor()。execute('...')
  • 在更新后调用transaction.commit()
  • 将Postgres隔离级别设置为SERIALIZABLE

网站运行apache / mod_wsgi,Django 1.8和Postgres 9.4,如果我在mod_wsgi配置中设置threads = 1 processes = 1,问题就会消失。我还用多个工人复制了gunicorn的问题。它是在Webfaction上托管的,尽管它会假设无所谓。

0 个答案:

没有答案
相关问题