I have models like:
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')
And a view that should do something like this:
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)
I know that this view is ugly but shows what I want to do.
And now the question is how to protect my self from a race condition when concurrent request appear? Is locking the table the only way?
Django 1.7.7, MySQL (transaction set to: READ COMMITED)