【问题标题】:Saving data in multiple DB backends as one atomic transaction, in Django在 Django 中,将多个数据库后端中的数据保存为一个原子事务
【发布时间】:2017-08-09 11:52:45
【问题描述】:

在我维护的 Django Web 应用程序中,我有一个 Redis 驱动的排序集,其中包含所有注册的用户名。此外,我还将上述用户名保存在 postgresql 数据库中(作为备份)。

具体来说,当用户注册时,我将他们的用户名同时保存在 DB 和 Redis 中,如下所示:

def save(self, commit=True):
    user = super(CreateAccountForm, self).save(commit=False)
    password = self.cleaned_data["password"]
    user.set_password(password)
    if commit:
        user.save() #saving in Postgresql DB
        insert_username(self.cleaned_data.get("username")) #inserting into Redis
    return user

if commit: 之后的行是动作发生的地方。

我如何确保在 DB 和 Redis 中保存自动,以便在它失败的情况下,我不会遇到数据完整性问题?一个说明性的例子会很棒。

【问题讨论】:

    标签: django django-models redis


    【解决方案1】:

    取自here,您可以这样做:

    from django.db import transaction
    
    def save(self, commit=True):
        user = super(CreateAccountForm, self).save(commit=False)
        password = self.cleaned_data["password"]
        user.set_password(password)
        if commit:
            with transaction.atomic():
                user.save()  #saving in Postgresql DB
                username = self.cleaned_data.get('username')
                insert_username(username)  #inserting into Redis
                # We are asserting that the username has been written to redis.
                # Otherwise, exception will be raised, not catched and transaction will be rolled back.
                assert get_username(username) == username
        return user
    

    【讨论】:

    • 我确信它可以回滚一个 postgresql 事务。 Redis 的呢?
    • Hmmm.. asserting 如果值已写入redis,如果没有,则提高?
    • 其实是的。您为什么不将其作为选项也包含在答案中,我会接受。涵盖所有基础。
    • 很高兴我能帮助@HassanBaig。最好的问候!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多