我们有一个 HTTP 端点,需要很长时间才能运行,并且也可以由用户并发调用。作为此请求的一部分,我们更新同步块(synchronized block)内的模型,以便其他(可能是并发的)请求获取该更改。
例如
MyModel m = null;
synchronized (lockObject) {
m = MyModel.findById(id);
if (m.status == PENDING) {
m.status = ACTIVE;
} else {
//render a response back to user that the operation is not allowed
}
m.save(); //Is not expected to be called unless we set m.status = ACTIVE
}
//Long running operation continues here. It can involve further changes to instance "m"
同步 block 的原因是为了确保即使是并发请求也能获取最新状态。但是,在请求完成之前,底层 JPA 不会提交我的更改 (m.save())。由于这是一个长时间运行的请求,我不想等到请求完成,并且仍然希望确保其他调用者收到状态更改的通知。我尝试调用“m.em().flush(); JPA.em().getTransaction().commit();”在 m.save() 之后,但这使得事务无法用于同一请求中的后续操作。我可以只给出“JPA.em().getTransaction().begin();”然后让 Play 处理交易?如果不是,处理这个用例的最佳方法是什么?
更新: 根据回复,我修改了代码如下:
MyModel m = null;
synchronized (lockObject) {
m = MyModel.findById(id);
if (m.status == PENDING) {
m.status = ACTIVE;
} else {
//render a response back to user that the operation is not allowed
}
m.save(); //Is not expected to be called unless we set m.status = ACTIVE
}
new MyModelUpdateJob(m.id).now();
在我的工作中,我有以下几行:
doJob() {
MyModel m = MyModel.findById(id);
print m.status; //This still prints the old status as-if m.save() had no effect...
}
我错过了什么?
最佳答案
将更新代码放入作业调用中
new MyModelUpdateJob(id).now().get();
因此更新将在作业结束时提交的另一个事务中完成
关于jpa - Play 1.2.3 框架 - 提交事务的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9278081/