mysql - Django 模型创建时的竞争条件

标签 mysql django concurrency transactions locking

我有这样的模型:

class Deck(models.Model):
    some_hash = models.CharField(max_length=64)
    store_id = models.CharField(max_length=256)
    tier = models.IntegerField()

class Card(models.Model):
    deck = models.ForeignKey(Deck, related_name='cards')

一个 View 应该做这样的事情:

class GetCardView(ApiView):  # ApiView from Django REST Framework
    response_json = get_some_data_from_external_service(
        request.GET['store_id'], request.GET['tier']
    )  # if this data for a store_id and tier changes a new Deck is needed

    deck, created = Deck.objects.get_or_create(
        some_hash=hashlib.sha256(response).hexdigest(), 
        store_id=request.GET['store_id'], tier=request.GET['tier']
    )
    if created:
        deck.add_cards(response_json)  # adds for e.g. 5 cards

    card = deck.pick_a_card()
    if not card: #  deck depleted
        Deck.objects.create(
            some_hash=hashlib.sha256(response).hexdigest(), 
            store_id=request.GET['store_id'], tier=request.GET['tier']
        )
        deck.add_cards(response_json)  # adds for e.g. 5 cards
        card = deck.pick_a_card()
    return Response(card)

我知道这个 View 很丑陋,但它显示了我想做的事情。
现在的问题是,当并发请求出现时,如何保护自己免受竞争条件的影响?锁定表是唯一的方法吗? Django 1.7.7,MySQL(事务设置为:READ COMMITED)

最佳答案

所以我并没有真正找到答案,因为现在我认为这个想法从一开始就很糟糕。
我最终没有存储 Card 模型,而是选择了带有 LFSR 的模型,并且只将种子存储在 Deck 模型中。这对我来说已经足够了。

供将来引用。您需要一些在 DB 级别失败的东西(如唯一约束),这将引发一些异常,您的逻辑可以在 transaction.atomic() 上下文管理器中识别。

具有READ-COMMITTED 隔离级别的MySQL 适用于get_or_create

感谢大家提供的信息。

关于mysql - Django 模型创建时的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29470694/

相关文章:

python - 根据另一个查询集的长度对一个查询集进行排序

Django : json serialize a queryset which uses defer() or only()

javascript - django ajax请求获取选定的索引

java - 如果我在 Spring Framework 的 @PostConstruct 中初始化对象属性,我应该将它们标记为 volatile 吗?

java - 如何区分 Java Futures?

haskell - 如何在 Haskell 中最好地同步游戏引擎和网络服务器?

mysql - 乘客未到达 MySql

mysql 2个表的并集

MySQL父子一查询选择

python - 安装 Postgis (PostgreSQL)(Django)(Mac OS x 10.7) 时遇到问题