Google App Engine - 添加&反映模式,解决最终的一致性

时间:2014-03-14 09:15:28

标签: django google-app-engine django-nonrel

我正在app引擎上构建一个Web应用程序。 就我而言,这是建立在django-nonrel之上的,但关键是它正在使用谷歌的数据存储。

我喜欢这样一个事实:我不需要处理复制,分片,备份等等,但有一件事总是妨碍我最终的一致性,这似乎妨碍了实现一个共同点网络应用程序模式,我称之为“添加和反映”。

假设我有一个项目管理应用程序。该项目是其核心模型。 现在有一个网页页面,我看到所有项目的列表,可以添加一个项目,然后我将反映所有项目的列表,其中应包括我刚刚添加的项目(假设没有错误)。

所以模式是这样的:

  1. 获取并显示现有项目列表
  2. 用户添加新项目(使用该页面上的表单)
  3. 创建新项目
  4. 作为回复,获取并显示现有项目的列表(现在包括新项目)
  5. 现在的情况是,由于最终的一致性,当我在添加新项目后立即获得所有项目的列表时,无法保证我将获得该新项目。 现在,如果在第一个用户(用户A)添加项目一秒后另一个请求(例如另一个用户:用户B)请求项目列表时发生这种瞬时不一致会很好,但是当用户A真的出现问题时执行操作,但没有看到他的行为结果,因此没有得到反馈。

    我已经习惯了这样的事情来解决这个问题:

    def create_project(request):
        response_context = {}
        new_project = Project(name=request.POST['name'])
        project.save()
        response_context['projects'] = Project.get_serialized_projects()
        # on GAE, eventual consistency means we are not guaranteed to see the
        # new projects while querying for all projects, therefore we might need 
        # to add it manually...
        if project.serialize() not in response_context['projects']:
            response_context['projects'].append(project.serialize())
        return render('projects.html', response_context)
    

    问题在于,这种情况发生在我的代码中的许多地方,所以我想也许我在那里遗漏了一些东西,因为这种模式是一种基本的Web应用程序模式。

    有关其他方法的任何建议吗?

1 个答案:

答案 0 :(得分:0)

是的,这是一个常见问题。没有没有神奇的修复。 从客户端一旦您知道提交成功,您就可以在本地保存项目(全局或存储),然后在从数据存储区查询时合并您保存的数据。把它过期就这样它是暂时的。在所有情况下使其工作并非易事(比如添加一个项目然后删除/重命名它以及更新缓存等)。 从服务器端开始,它可以在memcache中缓存最近的保存,并且还可以与您的查询合并。