Django unique_together抛出服务器错误,不知道为什么

时间:2015-01-17 22:14:41

标签: python mysql django multithreading

好的,这是一些背景知识,我们使用django和mysql为我们的应用程序构建了一个消息传递系统。我们内置了read_receipts来告诉用户何时需要读取线程。每当调用我们的API端点get_messages时,我们都会创建一个read_receipt,并返回任何新消息。在应用程序中,如果用户打开了一个线程,则每隔5秒调用一次get_messages。读取收据对于线程和用户来说是唯一的(即,每个线程和用户只有一个read_receipt,但是线程或用户可以'拥有'多个read_receipts)。我们经常遇到服务器错误,其中尝试创建具有相同线程和用户的read_receipt以及另一个read_receipt。我们创建read_receipts的唯一地方是我在下面发布的create_individual_message_read_receipt()。我很难过,因为代码应该确保已经为用户删除了read_receipt,并且在它创建另一个之前它是否存在。有任何想法吗?我认为这可能与通话的频率有关,但我们曾希望交易可以解决这个问题。

class IndividualMessageThreadReadReceipt(models.Model):
"""
Stores whether user has read the most recent message
"""

    thread = models.ForeignKey(
    IndividualMessageThread, related_name='read_receipts')

    user = models.ForeignKey('accounts.User')

    last_read_message = models.ForeignKey('messages.IndividualMessage')

    last_updated = models.DateTimeField(auto_now_add=True)

    class Meta(object):
        ordering = ('id',)
        unique_together = ('user', 'thread')



@transaction.commit_manually()
def create_individual_message_thread_read_receipt(individual_thread,
                                              message, user):
"""
create message read receipt between individuals, deletes the old
receipt so the receipt should be unique for the user and thread
"""
    try:
        ind_read_receipt = (IndividualMessageThreadReadReceipt.objects
                            .select_for_update().get(
                                thread=individual_thread.id,
                                user=user.id))
        if ind_read_receipt.last_read_message_id < message.id:
            ind_read_receipt.delete()
            IndividualMessageThreadReadReceipt.objects.create(
                thread=individual_thread, last_read_message=message,
                user=user)
    except IndividualMessageThreadReadReceipt.DoesNotExist:
        IndividualMessageThreadReadReceipt.objects.create(
            thread=individual_thread, last_read_message=message, user=user)
    transaction.commit()

0 个答案:

没有答案