我对此代码有几个问题:
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(....);
}
不推荐使用Akka.future,我应该按照here的说明使用Promise 。它比较冗长。你好吗?
由于数据库中的并行写入,这会导致乐观锁异常。 我应该把呼叫封装在一起吗?
由于
答案 0 :(得分:0)
在这个例子中,你看起来并不等待期货完成;假设你真的不需要,承诺不会更冗长,因为你可以忽略返回的承诺,只需从你的方法返回就像你在这里做的那样。唯一的区别在于API名称:“Callable”变为“Function0”,“call”变为“apply”。
这取决于它们是否是逻辑序列,如果它们真的是独立的并且应该同时运行。如果第一个适用,那么你应该将主体抽象为局部方法并按顺序调用它们,否则让它们同时运行是正确的。在这种情况下,您可以使用乐观锁定并执行重试(用户触发,这可能更常见于乐观锁定,或自动,取决于您的情况)或更改为悲观锁定和隔离级别(这可能会对您产生负面影响)性能因为它最常用于数据库级锁定以及更高的资源争用。)
答案 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替换为您的版本前缀。