Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 重头戏1.2.3框架-提交事务的正确方式_Jpa_Playframework - Fatal编程技术网

Jpa 重头戏1.2.3框架-提交事务的正确方式

Jpa 重头戏1.2.3框架-提交事务的正确方式,jpa,playframework,Jpa,Playframework,我们有一个HTTP端点,需要很长时间才能运行,用户也可以并发调用它。作为该请求的一部分,我们在同步块内更新模型,以便其他(可能并发的)请求获取该更改 例如 之所以使用同步块,是为了确保即使是并发请求也能获取最新状态。但是,在请求完成之前,底层JPA不会提交我的更改(m.save())。因为这是一个长时间运行的请求,所以我不想等到请求完成后再等待,而是希望确保其他呼叫者收到状态更改的通知。我试图在m.save()之后调用“m.em().flush();JPA.em().getTransaction

我们有一个HTTP端点,需要很长时间才能运行,用户也可以并发调用它。作为该请求的一部分,我们在同步块内更新模型,以便其他(可能并发的)请求获取该更改

例如

之所以使用同步块,是为了确保即使是并发请求也能获取最新状态。但是,在请求完成之前,底层JPA不会提交我的更改(m.save())。因为这是一个长时间运行的请求,所以我不想等到请求完成后再等待,而是希望确保其他呼叫者收到状态更改的通知。我试图在m.save()之后调用“m.em().flush();JPA.em().getTransaction().commit();”,但这会使事务无法作为同一请求的一部分用于后续操作。我可以只给出“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();

因此,更新将在作业结束时提交的另一个事务中完成

哎哟,一旦您添加更多播放服务器,您就会遇到麻烦。您可能希望在示例中使用乐观锁定,或者我建议不要使用悲观锁定

但是,看看你的代码,也许可以读一下这篇文章。我不确定在这种情况下你是否需要一个同步块……试着去做幂等的

就你而言,如果 1.用户1和用户2都调用该方法,该方法处于挂起状态,然后它变为活动(幂等) 如果用户1或用户2赢了,那么不管怎样,这就像你有了同步块一样

不过,我相信这里没有展示一个更复杂的场景,但请阅读这篇基于流沙的文章,因为它确实改变了传统的思维方式,也改变了谷歌、亚马逊和超大规模系统的运作方式

跨play服务器的分布式事务的另一个选择是zookeeper,大型nosql人员使用它,但仅作为最后手段;);)

后来,,
院长

谢谢。我已经根据你的回复更新了我的帖子。简言之,作业似乎没有获得行的更新,并且仍然看到旧状态。@Ananth您检查了吗?在我看来,如果您还告诉控制器方法您希望等待作业完成,则双作业设置应该可以工作。对播放控制器的调用是一个事务。因此,当http请求/响应完成时,您将看到控制器中所做的修改。在您的工作中,您无法看到在控制器中完成的事情,因为该方法尚未完成。您必须基于此重新思考代码。你还必须注意迪恩说的话。出于业务目的使用同步块不是一种好的做法,而且这不会扩展
new MyModelUpdateJob(id).now().get();