播放模型保存函数实际上并未写入数据库



我有一个名为"JobStatus"的播放模型,它只有一个属性,一个带有JobState的枚举(Runing/notRunning)。

该类扩展了模型,并作为单例实现。您可以调用它的getInstance()方法来获取基础表中的唯一记录。

我有一个每月运行的作业,在该作业中,我会在不同的时间来回切换JobStatus对象的状态,并调用.save().

我注意到它实际上并没有节省开支。

当作业开始时,它的第一行代码是

JobStatus thisJobStatus = jobStatus.getInstance();
...// exit if already running
thisJobStatus.JobState = JobState.Running;
thisJobStatus.save()

则当作业完成时,它将把状态改回NotRunning并再次保存。

问题是,当我在MySql数据库中查找时,实际记录值从未更改。

这会导致灾难性的失败,因为当其他节点尝试运行作业时,它们会检查状态,并且由于它们将其视为NotRunning,所以它们都会尝试运行作业。

因此,我管理作业状态的聪明方案失败了,因为实际价值没有被提交给DB。

当我对模型调用.save()时,如何强制Play立即写入数据库?

谢谢Josh

尝试将其添加到JobStatus中,并在保存后调用它。

public static void commit(){
    JobStatus.em().getTransaction().commit();
    JobStatus.em().getTransaction().begin();
    JobStatus.em().flush();
    JobStatus.em().clear();
}

我想你想把你的作业标记为"正在运行",就像作业开始时的第一件事一样?在这种情况下,您还不应该有任何其他正在进行的数据库语句。。。

要立即在数据库中提交更改(而不是在作业结束后),请在thisJobStatus.save();方法调用后添加以下命令:

JPA.em().flush();
JPA.em().getTransaction().commit();

此外,由于您使用的是MySQL,您可能希望在使用SELECT ... FOR UPDATE子句重试时立即锁定该行。(更多信息请参阅MySQL参考手册。)当然,您不希望在getInstance()方法中有这样的内容,否则每次提取操作都会锁定记录。

相关内容

最新更新