2016-06-10 107 views
0

我想使用Spring MVC在表中添加一些虛擬數據。Java防止併發訪問Spring MVC中的方法

下面是代碼: -

在道

public int generateData(){ 
    int iData = 80001; 
    String qry = "SELECT p FROM TestDomain p"; 
    List<TestDomain> runQry = daoHelper.findByQuery(qry); 
    if(runQry.size()!=0){ 
     TestDomain tdom = runQry.get((runQry.size()-1)); 
     iData = tdom.getNum_data(); 
     iData++; 
    } 


    return iData; 
} 

這產生要添加到表中的一個整數列的虛設值。基本上,如果表格是空的,它會生成80001,否則增加現有的最大值。請注意,由於某些需求限制,我無法使該列獨一無二。從上述函數獲取數據後,我只需使用合併函數將其插入表中。

entityManager.merge(entity); 

現在的問題是,當多個用戶打在同一時間生成函數,它們分配相同的數據,這將導致duplicacy當數據被不同的客戶推到桌子上。我如何防止這種重複?

編輯..

1,我已經嘗試過在我的生成方法的Java synchronized關鍵字,它不工作,也許是因爲我使用了Spring的事務,我的服務層。

2,我不能使用數據庫序列來生成唯一的數據,數據必須來自生成方法。

回答

1

它不是Spring MVC數據重複問題的問題。您的應用程序需要通過控制對生成id(或)的方法的併發訪問來防止數據重複,因爲首選方法是使用數據庫序列獲取下一個id,而不是生成id的應用程序。

如果你不能使用數據庫序列,並仍想使用生成方法,然後你的應用程序需要通過添加JAVA 同步關鍵字生成方法(和/或)鎖定任何對象,允許單一控制併發或者線程訪問該方法。這將使其他用戶/線程等待,直到執行此方法。

+0

java synchronized關鍵字不適用於我。也許是因爲我在使用spring事務服務。我已經編輯了我的原始問題以包含這條信息 –

+0

您是否嘗試將整個生成方法保存在像這樣的同步塊中public int generateData(){synchronized {.....}} –

+0

是的,我保留了整個生成方法在同步塊 –

1

看看hibernate中的@Version註解。它可能會解決你的問題。

或者,你可以做的是在執行操作時使用悲觀鎖定和鎖定你的表。

+0

謝謝謝爾文,但我不關心更新相同的記錄,我只是同時插入多個記錄,因此我懷疑樂觀鎖定會幫助我在這種情況下。 Kndly糾正我,如果我錯了.. –

+0

你的閱讀和寫在同一個交易?直到事務處理方法完成後,Hibernate纔會寫入數據庫。所以你需要確保你的交易也符合你寫/讀數據庫的方式。它更好地使用鎖定,而不是同步。即:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock。html –

+0

我的生成方法讀取數據庫並生成要寫入的數據和實際的寫入方法在不同的事務中。 –