2016-04-28 89 views
0

我有一個方法可變參數線程安全的靜態方法?

public static Person updatePersonId (Person person) 
{ 
    // If the ID of the person reaches the maximum ID in our predefined range in configuration then reset the ID from the start otherwise it will cross the range we defined. 
    if (person.getNewID().longValue() == person.getLastPossibleID().longValue()) 
    { 
     person.setNewID (person.getFirstID()); 
    } 

    // add 1 to Old ID to get new ID 
    person.setNewID (person.getNewID + 1); 

    return person; 
} 

我使用Hibernate來將其更新到數據庫中。正如你所看到的,我不能在同一個ID的數據庫中擁有一個以上的人(因爲我們總是將其以前的ID加1)。

現在的問題是,當我同時運行我的應用程序,即同時發生兩個事務時,分配給人的ID有時例如重複。

Database row 

PersonID  PersonName 

    1     Bob 
    2     Robert 
    2     Daniel 

是我創建的方法,而不是線程安全的?我應該添加Synchronized關鍵字嗎?

+1

我的方法不是線程安全的嗎?我應該添加Synchronized關鍵字嗎? NO使用DB序列 –

+0

@ScaryWombat,OP需要一個循環序列。 – shmosel

+0

但是人們,我們可以做到這一點沒有序列?我的方法不是線程安全的嗎?併發問題明顯造成重複ID? – Aiden

回答

1

是的,這種方法不是線程安全的。至於,兩個線程可以的Sametime達到這一行: -

person.setNewID (bnkPrb.getNewID + 1); 

但同步處理資料全法將放緩平定碼,所以採取鎖定僅此行: -

公共靜態人updatePersonId(人的人) { //如果該人的ID達到在我們的配置預定義的範圍內的最大ID然後重置從一開始就ID否則會越過我們定義

if (person.getNewID().longValue() == person.getLastPossibleID().longValue()) 
{ 
    person.setNewID (person.getFirstID()); 
} 

// add 1 to Old ID to get new ID 
syuncronized(this){ 
person.setNewID (bnkPrb.getNewID + 1); 
} 


return person; 
} 

然而範圍,BES t方法在數據庫端具有自動增量列或序列。

+0

謝謝你一堆。我現在明白了:) – Aiden

+0

問題是,如果我使用序列,而不是同步代碼,那麼如果一個事務回滾,那麼ID將會有差距。如果我必須確保身份證件沒有空白,該怎麼辦? – Aiden

+0

你是否真的需要它,因爲你採取的任何方法都會妨礙性能。由於你下一個行動將不得不等到第一個完成。即使對於syncronize,您也需要同步整個方法。 – Panther