gpt4 book ai didi

django - 在 Django 中为拍卖玩具应用处理并发的最佳方法

转载 作者:行者123 更新时间:2023-12-01 06:45:12 25 4
gpt4 key购买 nike

我正在 Django 中实现一个拍卖玩具应用程序,并且对如何在下面的代码中最好地处理并发感到困惑。我不确定我的哪个候选解决方案(或任何其他解决方案)最适合 Django 的设计。我对 Django/python 相当陌生,而且我的 SQL 知识很生疏,所以如果这是一个明智的选择,我深表歉意。

要求:用户可以对产品进行投标。只有当出价高于之前对同一产品的出价时,才会被接受。

这是模型的精简版本:

class Product(models.Model):
name = models.CharField(max_length=20)

class Bid(models.Model):
amount = models.DecimalField(max_digits=5, decimal_places=2)
product = models.ForeignKey(Product)

和投标 View 。这是发生竞争条件的地方(见评论):
def bid(request, product_id):
p = get_object_or_404(Product, pk=product_id)
form = BidForm(request.POST)
if form.is_valid():
amount = form.cleaned_data['amount']

# the following code is subject to race conditions
highest_bid_amount = Bid.objects.filter(product=product_id).aggregate(Max('amount')).get('amount__max')
# race condition: a bid might have been inserted just now by another thread so highest_bid_amount is already out of date
if (amount > highest_bid_amount):
bid = Bid(amount=amount, product_id=product_id)
# race condition: another user might have just bid on the same product with a higher amount so the save() below is incorrect
b.save()
return HttpResponseRedirect(reverse('views.successul_bid)'

到目前为止我考虑过的候选解决方案:
  • 我已经阅读了关于事务的 Django 文档,但我不知道如何将它们应用于我的问题。由于数据库不知道出价必须递增的要求,因此不会导致 Django 抛出 IntegrityError。有没有办法在模型定义期间定义这个约束?还是它误解了事务 API?
  • 存储过程可以处理出价逻辑。在我看来,到目前为止,这似乎是“最佳”选择,但它将竞争条件的处理转移到了底层数据库系统。但是,如果这是一个好方法,此解决方案可能会与解决方案 1 结合使用吗?
  • 我考虑使用 select_for_update 调用来锁定该产品的出价。但是,这似乎不是解决方案,因为据我所知,这不会影响任何新的出价?

  • 愿望 list :
  • 如果有任何可能,我想避免锁定整个投标表,因为无论如何都不会影响其他产品的投标。
  • 如果在应用程序级别有一个好的解决方案,我希望代码独立于底层数据库系统。

  • 非常感谢您的想法!

    最佳答案

    您可以添加一个highest_bid吗?列到 Products .如果我的逻辑没有关闭,您可以更新最高出价where product_id = x and highest < current_bid .如果此查询表明某行已更新,则将新记录添加到出价表中。这可能意味着您必须为highest_bid 列设置默认值。

    关于django - 在 Django 中为拍卖玩具应用处理并发的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6285883/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com