【问题标题】:Write to GAE datastore asynchronously异步写入 GAE 数据存储
【发布时间】:2011-09-22 09:04:37
【问题描述】:

在我的 Java 应用程序中,有时我的用户会执行一些需要写入数据存储区的工作,但我不想让用户在数据存储区写入时等待。我想在数据存储在后台时立即向用户返回响应。

似乎很清楚,我可以通过使用 GAE 任务队列、将任务排入队列来存储数据来做到这一点。但我也看到有一个 Async 数据存储 API,这似乎比处理任务队列要容易得多。

我可以只调用 AsyncDatastoreService.put() 然后从我的 servlet 返回吗?该 API 会在不让我的用户等待的情况下存储我的数据吗?

【问题讨论】:

    标签: java google-app-engine asynchronous


    【解决方案1】:

    我认为你是对的,异步调用看起来更容易。但是,AsyncDatastore 的 docs 提到了您应该考虑的一个警告:

    注意:在调用 get() 方法之前不会抛出异常。调用此方法可以验证异步操作是否成功。

    该注释中的“get”正在被异步调用返回的 Future 对象调用。如果您只是从您的 servlet 返回而没有对 Future 对象调用 get,您可能无法确定您的 put() 是否有效。

    使用排队任务,您可以更明确地处理错误情况,或者仅依靠自动重试。如果您想要排队的只是数据存储放置,您应该能够创建(或找到)一个为您完成大部分工作的实用程序类。

    【讨论】:

      【解决方案2】:

      很遗憾,这里没有任何真正好的解决方案。您可以将任务排入队列,但这样做有几个大问题:

      • 任务负载的大小受到限制,并且该大小小于实体大小限制。
      • 将记录写入数据存储实际上非常快,在挂钟时间内。成本的很大一部分也是序列化数据,无论如何您都必须将其添加到任务队列中。
      • 通过使用任务队列,您可以创建更多的最终一致性 - 用户可能会返回并看不到他们的更改已应用,因为任务尚未执行。您可能还会引入事务问题 - 您如何处理并发更新?
      • 如果出现故障,应用用户更新可能需要很长时间。在这种情况下,最好只向用户返回一个错误。

      我的建议是尽可能使用异步 API,但始终直接写入数据存储区。请注意,正如彼得指出的那样,您需要等待所有未完成的 API 调用,否则您将不知道它们是否失败 - 如果您不等待它们,应用服务器会在向用户返回响应之前.

      【讨论】:

      • 这是您在答案末尾提到的一个有趣的花絮。文档似乎没有提到如果您没有明确等待未完成的呼叫会发生什么。您是说应用服务器会跟踪您的哪些呼叫仍未完成,并在向用户返回响应之前自动阻止它们?这可能是对文档的一个很好的补充。
      • @Peter 没错。事实上,在开发服务器中,您的调用可能甚至不会执行,除非您专门等待它。
      【解决方案3】:

      如果您需要的只是让用户拥有一个响应式界面,而数据库后面的东西在搅动,那么您所要做的就是在客户端级别进行异步调用,也就是做一些发送数据库写入的 ajax请求,立即更改用户显示,然后在 ajax 请求回调时根据您的需要更新视图。

      您可以轻松地将 GWT 支持添加到您的 GAE 项目(通过 eclipse 插件或 maven gae 插件),并有时间做异步工作。

      【讨论】:

      • 我同意使用 AJAX 通常是个好主意。就我而言,用户正在执行整页表单 POST,因此不适合。
      • 是的,但是看,在他提交表单和数据库完成处理(并且帖子响应)之间的很长时间之后,您现在显示什么?只需让帖子异步提交(jquery 和原型都为此提供工具)立即显示内容,并在回调返回后使用数据库提交的状态更新显示(如页面标题或其他内容)
      猜你喜欢
      • 2013-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多