玩!框架异步调用修改数据库的同一对象

时间:2014-08-13 15:17:33

标签: web-services postgresql asynchronous akka playframework-2.2

我对此代码有几个问题:

public static Result submit() {

        final Object object = filledForm.get();

        Akka.future(new Callable<Void>() {
            public Void call() throws Exception {
                 WS1...
                 object.save();
            });

        Akka.future(new Callable<Void>() {
            public Void call() throws Exception {
                 WS2...
                 object.save();
            });

        return ok(....);
}
  1. 不推荐使用Akka.future,我应该按照here的说明使用Promise 。它比较冗长。你好吗?

  2. 由于数据库中的并行写入,这会导致乐观锁异常。 我应该把呼叫封装在一起吗?

  3. 由于

2 个答案:

答案 0 :(得分:0)

  1. 在这个例子中,你看起来并不等待期货完成;假设你真的不需要,承诺不会更冗长,因为你可以忽略返回的承诺,只需从你的方法返回就像你在这里做的那样。唯一的区别在于API名称:“Callable”变为“Function0”,“call”变为“apply”。

  2. 这取决于它们是否是逻辑序列,如果它们真的是独立的并且应该同时运行。如果第一个适用,那么你应该将主体抽象为局部方法并按顺序调用它们,否则让它们同时运行是正确的。在这种情况下,您可以使用乐观锁定并执行重试(用户触发,这可能更常见于乐观锁定,或自动,取决于您的情况)或更改为悲观锁定和隔离级别(这可能会对您产生负面影响)性能因为它最常用于数据库级锁定以及更高的资源争用。)

答案 1 :(得分:0)

如果在两次调用完成后保存对象更新,则完全避免锁定问题。因此,您可以使用Promise将您的呼叫组合在一起,如下所示:

public static Promise<Result> submit() {
final Object object = filledForm.get();
Promise<JsonNode> jsonPromise1 = ws.url("url1").get().map(
    new Function<WSResponse, JsonNode>() {
        public JsonNode apply(WSResponse response) {
            JsonNode json = response.asJson();
            return json;
        }
    }
);
Promise<JsonNode> jsonPromise2 = ws.url("url2").get().map(
    new Function<WSResponse, JsonNode>() {
        public JsonNode apply(WSResponse response) {
            JsonNode json = response.asJson();
            return json;
        }
    }
);
 return Promise.sequence(jsonPromise1,jsonPromise2).map(
 new Function<WSResponse, Result>() {
        public JsonNode apply(List<JsonNode> results) {
            //populate object
           object.save();
            return ok(...);
        }
    });
}

如果您需要依赖第一个电话中的信息来制作第二个信息,您可以像return promise1.flatMap(){ return promise2.map { object.save()}}一样将承诺链接在一起

不要忘记添加恢复功能,以防您的通话失败。

如需完整示例,请查看https://www.playframework.com/documentation/2.4.x/JavaWS,如果您使用的是旧版本的游戏,请将2.4.x替换为您的版本前缀。