Play Model保存功能实际上并没有写入数据库

时间:2012-03-06 00:31:34

标签: jpa playframework

我有一个名为“JobStatus”的游戏模型,它只有一个属性,一个带有JobState的枚举,(Running / notRunning)。

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

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

我注意到它实际上并没有保存。

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

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

thisJobStatus.JobState = JobState.Running;
thisJobStatus.save()

然后当作业完成时,它会将状态更改回NotRunning并再次保存。

问题在于,当我查看MySql数据库时,实际记录值永远不会改变。

这会导致灾难性故障,因为当其他节点尝试运行作业时,他们会检查状态,因为他们将其视为NotRunning,所以他们都会尝试运行该作业。

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

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

由于 约什

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

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

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

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

此外,由于您使用的是MySQL,因此您可能希望在使用SELECT ... FOR UPDATE子句后立即锁定该行。 (有关详细信息,请参阅MySQL Reference Manual。)当然,您不希望在getInstance()方法中使用此方法,否则每次提取操作都会锁定记录。