2012-03-06 51 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

相關問題