0

Some example code showing the issue:

class Post(models.Model):
  ...

class Comment(models.Model):
  ...
  post = models.ForeignKey(Post, related_name='comments',
                      on_delete=models.CASCADE, null=False)
  post_comment_number = models.PositiveIntegerField(unique=True, null=False)

Say every time we create a new Comment object for a Post object, we want to assign the post_comment_number field a value that's +1 of the post_comment_number value of the last comment created for the same Post object.

I believe doing something like below could lead to a race condition issue:

last_comment_for_post = Comment.objects.filter(post=post).order_by('-post_comment_number')[0]

comment = comment_form.save(commit=False)
comment.post_comment_number = last_comment_for_post.post_comment_number + 1
comment.save()

How can we do this in a thread-safe way that wouldn't lead to a race condition issue?

Joe
  • 173
  • 10
  • what do you mean that lead a race condition? – seuling Jun 25 '18 at 02:02
  • @seuling Here is a link describing the race condition issue: https://stackoverflow.com/questions/34510/what-is-a-race-condition. Let me know if it doesn't make sense and I'll clarify. – Joe Jun 25 '18 at 03:29
  • btw, is there any reason you to use pk for post_comment_number? – seuling Jun 25 '18 at 05:00
  • @seuling - the primary key of the comments is not specific to a particular blog post. So, say, we have two blog posts A and B. I want blog A to have comments, each numbered starting from the number 1 - like comment #1, comment #2, comment #3. And I want to have the same thing under blog post B, or any other blog post. If I use the pk of comments, I'll end up with random comment IDs under each blog post. – Joe Jun 25 '18 at 05:26

1 Answers1

0

I would let the template handle the comment number rather than storing that in the database:

{% for comment in comments %}
    Comment #{{ forloop.counter }}
{% endfor %}

If you wanted to link to a comment to scroll to that particular block, use the PK of the comment:

<a href="#comment24">my comment</a>

{% for comment in comments %}
    <div id="comment{{ comment.pk }}">
        Comment #{{ forloop.counter }}
    </div>
{% endfor %}
gradiian
  • 1
  • 3