异步写入GAE数据存储区

时间:2011-09-21 16:51:10

标签: java google-app-engine asynchronous

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

似乎很清楚,我可以通过使用GAE任务队列来执行此操作,将任务排入队列来存储数据。但我也看到有一个Async数据存储区API,看起来它比处理任务队列要容易得多。

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

3 个答案:

答案 0 :(得分:3)

我认为Async调用似乎更容易。但是,AsyncDatastore的docs提到了您应该考虑的一个警告:

  

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

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

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

答案 1 :(得分:1)

不幸的是,这里没有任何真正好的解决方案。你可以排队任务,但是有几个大问题:

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

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

答案 2 :(得分:0)

如果你需要的只是让用户拥有一个响应式接口而后面的东西在数据库后面进行搅拌,你所要​​做的就是在客户端级别进行异步调用,也就是做一些发送db写入的ajax请求,更改用户显示的imemdiatelly,然后在ajax请求回调时,用你想要的任何内容更新视图。

您可以轻松地向您的GAE项目添加GWT支持(通过eclipse插件或maven gae插件)并让您的生活中有时间做异步操作。