我希望我能解釋得很好,因爲我的問題非常依賴於時間。所有灰熊工作者想要插入(SQL)首先插入灰熊,第二個SQLIntegrityConstraintViolationException
我有一個客戶端發送數據到服務器(Java)。在服務器上,我有一個RestServer等待來自客戶端的輸入。
當客戶端向服務器發送數據時,它會多次發送這些數據,直到它從服務器收到「okay-response」。 不幸的是,服務器的這個「OK」可能需要一些時間,因爲當服務器從客戶端獲取數據時,他必須在客戶端收到響應之前做很多事情(插入到數據庫中...)。
但是在服務器上的灰熊員工的工作時間內,客戶端再次向服務器發送數據,並且服務器上的下一個灰熊工人(灰熊工人數字2開始),並嘗試將其插入到數據庫中。
發生這種情況是因爲在灰熊工作人員2啓動之前,灰熊工人尚未完成插入數據庫並檢查數據是否已存在於數據庫中。灰熊工作者二認爲「沒有數據沒有插入數據庫,因此我要插入」。
希望我的照片能展現我所試圖解釋: multithreading problem
兩個工人認爲他們必須插入到數據庫中,雖然灰熊工人一人仍然試圖插入到數據庫。
我該如何告訴灰熊工作者,已經有一名灰熊工人試圖插入數據庫?
或者我該如何阻止灰熊工人兩秒? 或者我該如何解決這個問題?
只有代碼,你可以在圖片中看到:
public void setPunkteFuerTanz(Wertung eineWertung)
throws SQLException, ClassNotFoundException
{
int anzahlPunkteIDs;
Integer runde = eineWertung.getRunde();
if(runde == 0)
{
//something to do here
}
/*Jurorid 1 ist Admin, der darf mehrere Zeilen schreiben, deshalb
*anzahlPunkteIDs immer 0 */
if(eineWertung.getJurorID() == 1)
{
anzahlPunkteIDs = 0;
}
else
{
anzahlPunkteIDs = Integer.valueOf(sqlFunctions.getResultFromCustomQuery(
"select count(punkteid) from punkte "
.concat("where jurorid=").concat(String.valueOf(eineWertung.getJurorID()))
.concat(" and tid=").concat(String.valueOf(eineWertung.getTanzID()))
.concat(" and runde=").concat(String.valueOf(runde))).toString());
}
if(anzahlPunkteIDs == 1)
{
//Tanz schon bewertet
sqlFunctions.setExecuteUpdate("UPDATE PUNKTE SET "
.concat("choreo=").concat(String.valueOf(eineWertung.getChoreo()))
.concat(",technik=").concat(String.valueOf(eineWertung.getTechnik()))
.concat(",level=").concat(String.valueOf(eineWertung.getLevel()))
.concat(",gesamt=").concat(String.valueOf(eineWertung.getGesamt()))
.concat(",futuretalent=").concat(String.valueOf(eineWertung.getFutureTalent()))
.concat(",bestchoreo=").concat(String.valueOf(eineWertung.getBestChoreo()))
.concat(",bestcostume=").concat(String.valueOf(eineWertung.getBestCostume()))
.concat(",runde=").concat(String.valueOf(runde))
.concat(" where jurorid=").concat(String.valueOf(eineWertung.getJurorID()))
.concat(" and tid=").concat(String.valueOf(eineWertung.getTanzID()))
.concat(" and runde=").concat(String.valueOf(runde)));
}
else
{
//Tanz noch nicht bewertet
int letztePunkteID;
Object letztePunkteIDObject =
this.sqlFunctions.getResultFromCustomQuery("select punkteid from punkte");
letztePunkteID = (letztePunkteIDObject == null) ?
0 : (Integer.valueOf(letztePunkteIDObject.toString())+1);
this.sqlFunctions.setExecuteUpdate("insert into punkte "
.concat("(punkteid,jurorid,choreo,technik,level,gesamt,")
.concat("futuretalent,bestchoreo,bestcostume,runde,tid) ")
.concat("values(").concat(String.valueOf(letztePunkteID)).concat(",")
.concat(String.valueOf(eineWertung.getJurorID())).concat(",")
.concat(String.valueOf(eineWertung.getChoreo())).concat(",")
.concat(String.valueOf(eineWertung.getTechnik())).concat(",")
.concat(String.valueOf(eineWertung.getLevel())).concat(",")
.concat(String.valueOf(eineWertung.getGesamt())).concat(",")
.concat(String.valueOf(eineWertung.getFutureTalent())).concat(",")
.concat(String.valueOf(eineWertung.getBestChoreo())).concat(",")
.concat(String.valueOf(eineWertung.getBestCostume())).concat(",")
.concat(String.valueOf(runde)).concat(",")
.concat(String.valueOf(eineWertung.getTanzID())).concat(")"));
// UPDATE 由於同步沒有工作,我試圖與合併查詢的提示。 由於我的合併聲明對於評論太長,所以我會在此更新它: 我想我已經通過合併查詢來完成它。取而代之的INSERT語句我寫了這個查詢:`
MERGE INTO punkte pu USING
(VALUES 1,2,3,1,5,5,5,5,5,5,5) temp (punkteid, tid,jurorid,runde,choreo,technik,level,gesamt,futuretalent,bestchoreo,bestcostume)
ON temp.punkteid = pu.punkteid
WHEN MATCHED THEN UPDATE SET
pu.punkteid=temp.punkteid,pu.tid = temp.tid,pu.jurorid=temp.jurorid,pu.runde=temp.runde,pu.choreo=temp.choreo,pu.technik=temp.technik,pu.level=temp.level,pu.gesamt=temp.gesamt,pu.futuretalent=temp.futuretalent,pu.bestchoreo=temp.bestchoreo,pu.bestcostume=temp.bestcostume
WHEN NOT MATCHED THEN
INSERT (punkteid, tid,jurorid,runde,choreo,technik,level,gesamt,futuretalent,bestchoreo,bestcostume) VALUES (temp.punkteid, temp.tid,temp.jurorid,temp.runde,temp.choreo,temp.technik,temp.level,temp.gesamt,temp.futuretalent,temp.bestchoreo,temp.bestcostume)`
//更新2
是的,謝謝大家的努力,它正在與「合併」就像一個魅力。
也是一個非常bigh感謝和信Gadellaa他的耐心,通過其他可能的解決方案
您應該使用hsqldb的Merge執行「upsert」操作。當該行不存在時,它會插入。當它存在時它會更新。 http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_merge_statement –
您必須使用MERGE語句作爲第一條評論的建議。這可以讓數據庫引擎用單個語句處理不同的情況。 – fredt