【发布时间】:2015-06-10 19:35:47
【问题描述】:
我有这样的模型:
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')
还有一个应该做这样的事情的视图:
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)
我知道这种观点很丑陋,但表明了我想要做的事情。
现在的问题是当并发请求出现时如何保护我自己免受竞争条件的影响?锁定桌子是唯一的方法吗?
Django 1.7.7,MySQL(事务设置为:READ COMMITED)
【问题讨论】:
-
Django如何让你指定“事务”的
BEGIN和COMMIT?我在您的代码中没有看到任何提示。 -
您可以简单地在
__enter__上执行with transaction.atomic():-BEGIN,COMMIT上__exit__,ROLLBACK上的异常。 -
可以通过包装事务并在
SELECTs上使用FOR UPDATE来处理许多“竞争条件”,从而导致执行UPDATE。 -
你可以在这里找到答案:stackoverflow.com/questions/2235318/…
标签: mysql django concurrency transactions locking