How to handle concurrency of bookmark system in django?
I tried to implement bookmark system for product, when users click bookmark button, it will be recorded in his bookmark table, and update bookmark count field in Product Model. However I faced DB Lock when there is too many request at the same time. Also, I realized that when users add or delete bookmark at the same time, there will be concurency issues like, users can not read Product Information or Bookmark count or DB Lock.. How to handle concurrency in my situation? I know the exclusive lock but it will lower the performance.. please help me..
here are my codes
class Bookmark(models.Model):
_id = models.AutoField(primary_key=True, editable=False)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='bookmark_user')
def __str__(self):
return str(self.user)
class BookmarkItems(models.Model):
_id = models.AutoField(primary_key=True, editable=False)
user = models.CharField(max_length=255, null=True, blank=True)
image = models.CharField(max_length=255, null=True, blank=True)
bookmark = models.ForeignKey(Bookmark, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
def image_preview(self):
if self.image:
return mark_safe('<img src="{0}" width="75" height="75" />'.format(self.image))
else:
return '(No image)'
def __str__(self):
return str(self.product)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def addBookmark(request):
user = request.user
user_id = request.data['user']
product_id = request.data['product_id']
image = request.data['image']
product = Product.objects.get(_id=product_id)
with transaction.atomic():
bookmark = Bookmark.objects.get_or_create(user=user)
Product.objects.filter(_id=product_id).update(
bookmark_count = F('bookmark_count') + 1
)
BookmarkItems.objects.create(
user = user_id,
image = image,
bookmark=bookmark[0],
product=product,
)
return Response({'success':'The bookmark has been created.'})
@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def deleteBookmark(request, pk):
user =request.user.id
with transaction.atomic():
Product.objects.filter(_id=pk).update(
bookmark_count = F('bookmark_count') - 1
)
BookmarkItems.objects.filter(user=user, product=pk).delete()
return Response({'success': 'The bookmark has been deleted.'})