2012-03-06 53 views
3

我有一个名为“JobStatus”的游戏模型,它只有一个属性,一个带有JobState的枚举(Running/notRunning)。Play模型保存功能实际上并没有写入数据库

该类扩展了模型,并以单例实现。您将其称为getInstance()方法以获取基础表中的唯一记录。

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

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

当工作开始了,这是第一行代码是

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

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

然后当工作完成,将改变状态回到notrunning状态并再次保存。

问题是,当我查看MySql数据库时,实际记录值从不改变。

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

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

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

感谢 乔希

+0

顺便说一句我试图宣布函数为非事务性的每个Play的文档,但没有奏效。 – 2012-03-06 00:56:54

+0

......如果是因为交易...... – 2012-03-06 00:57:14

+0

我只想到这可能是因为切换作业状态并将其写入数据库是一种在长时间运行的作业中发生的操作。 – 2012-03-06 00:57:59

回答

3

尝试添加这对您的JobStatus后把它保存。

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

这部分工作,状态设置为“运行”,然后工作运行,但在工作结束时,当我去改变状态回“NotRunning”,然后我调用.save()然后。 commit(),在我现有的JobStatus实例上,出现以下错误。发生PersistenceException:org.hibernate.PersistentObjectException:传递给persist的detached实体:models.JobStatus。初始保存后,我的实例不再有效吗?我是否需要再次调用getInstance()以从数据库中重新查询它? – 2012-03-06 19:39:21

+0

我是如此聪明的SMRT。我不得不从DB重新填充对象。所以现在我有一个帮手功能。 '//帮助管理工作状态 \t private void MarkJobRunning(){ \t \t BillingJob thisJob = BillingJob.getInstance(); \t \t thisJob.state = JobState.Running; \t \t thisJob.save(); \t \t thisJob.commit(); \t} \t \t 私人无效MarkJobNotRunning(){ \t \t BillingJob这份工作是= BillingJob.getInstance(); \t \t thisJob.state = JobState.NotRunning; \t \t thisJob.save(); \t \t thisJob.commit(); \t}'非常感谢@ emt14!尽管这是一个很好的做法吗?我现在试图为我的所有模型添加一个提交方法。 – 2012-03-06 19:48:39

+0

我不确定这是好还是不好的做法。但是,您的工作将在事务中运行,因此这是在作业仍在运行时将数据保存到数据库的唯一方法。实际上还有另一个。从最初的工作中调用另一份工作是可能的。第二项工作将开始一项单独的事务,并且在第一项工作仍在运行的同时,该项工作中修改的数据将被保留。 – emt14 2012-03-07 05:29:45

0

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

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

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

此外,由于你使用MySQL,你可能想使用SELECT ... FOR UPDATE条款在retriveval立即锁定该行。 (有关更多信息,请参见MySQL Reference Manual)。当然,您不希望在getInstance()方法中使用该方法,否则每个提取操作都会锁定该记录。

+0

昨天我尝试了这一堆汤姆,但它始终导致错误,当工作的数据库语句开始时。 @ emt14的解决方案奏效。通过将事务提交放入实际模型本身的函数中,提交似乎不会破坏剩余的工作。 – 2012-03-06 19:51:03

相关问题