Java Play Framework 2.5.4异步休眠操作
如何使用Akka在使用Hibernate的数据库上执行操作而不阻塞web客户端 更新: 结果表明错误是由dao.get()方法引起的。我更改了start()方法,从数据库中获取一个实际对象而不是id,现在我没有得到任何错误,但什么也没有发生(正如我前面所说,它被困在em.merge()上) 我得到了同样的错误。@Transactional注释是在同步方法上的。我想您需要在异步块中进行事务处理。您可以使用for jpa方法withTransaction代替注释。 其签名(来自)Java Play Framework 2.5.4异步休眠操作,java,hibernate,playframework,playframework-2.5,Java,Hibernate,Playframework,Playframework 2.5,如何使用Akka在使用Hibernate的数据库上执行操作而不阻塞web客户端 更新: 结果表明错误是由dao.get()方法引起的。我更改了start()方法,从数据库中获取一个实际对象而不是id,现在我没有得到任何错误,但什么也没有发生(正如我前面所说,它被困在em.merge()上) 我得到了同样的错误。@Transactional注释是在同步方法上的。我想您需要在异步块中进行事务处理。您可以使用for jpa方法withTransaction代替注释。 其签名(来自) 通过调用jpa实
jpa.withTransaction("default", true, ()->doStuff(dao.get(id)), play.libs.concurrent.HttpExecution.fromThread(ec))
.thenApply(i -> ok("Got result: " + i)));
注意,调用withTransaction中的第二个参数true用于只读操作(在您的例子中)我用@asch的建议解决了这个问题: 控制器:
@Inject
JPAApi jpa;
@Inject
private JPAApi jpa;
[...]
return CompletableFuture.supplyAsync(() -> jpa.withTransaction("default", false, ()-> doStuff(objectDAO.get(id))), play.libs.concurrent.HttpExecution.fromThread(ec))
.thenApply(i -> ok("Got result: " + i));
在doStuff方法类中:
private static final JPAApi jpaApi = Play.current().injector().instanceOf(JPAApi.class);
[...]
jpaApi.withTransaction(() -> {
EntityManager em = jpaApi.em();
em.merge(object);
});
[...]
您好,我找不到任何带有该签名的“withTransaction”方法。我编辑了答案-添加了签名并链接到API文档。我在我的项目中使用这种方法,只是我同步进行。我更喜欢它而不是@Transactional annotation(别忘了删除它!)。您是否同时删除了@Transactional annotation(代码段中有两个)。也许JPA应该被注入异步方法本身的一个作用域中。我将尝试不同的注射,并在这里公布结果。谢谢。我尝试了不同的方法,比如将JPAApi作为参数发送给方法,将方法移动到另一个类,为每个进程创建一个新实例+注入JPAApi,等等。但是我仍然得到相同的错误。也许我做得不对,所以我的问题更简单:如何使用Play的Akka Actors实现非web客户端阻塞数据库操作?例如,启动一些更新操作,将某些字段设置为某些值,而不让发送控制器操作的客户端等待结果(因为它与用户无关)。
/**
* Run a block of code in a JPA transaction.
*
* @param name The persistence unit name
* @param readOnly Is the transaction read-only?
* @param block Block of code to execute
* @param <T> type of result
* @return code execution result
*/
public <T> T withTransaction(String name, boolean readOnly, Supplier<T> block);
@Inject
JPAApi jpa;
jpa.withTransaction("default", true, ()->doStuff(dao.get(id)), play.libs.concurrent.HttpExecution.fromThread(ec))
.thenApply(i -> ok("Got result: " + i)));
@Inject
private JPAApi jpa;
[...]
return CompletableFuture.supplyAsync(() -> jpa.withTransaction("default", false, ()-> doStuff(objectDAO.get(id))), play.libs.concurrent.HttpExecution.fromThread(ec))
.thenApply(i -> ok("Got result: " + i));
private static final JPAApi jpaApi = Play.current().injector().instanceOf(JPAApi.class);
[...]
jpaApi.withTransaction(() -> {
EntityManager em = jpaApi.em();
em.merge(object);
});
[...]