我有以下幾點:休眠:在實體更新欄只有當特定字段爲空
public class Member {
@Id
@Column
private String id;
@Column
private String location;
// setters/getters
}
我要實現以下業務規則:
設置位置:
- 獲取來自基於ID的數據庫成員。
- 如果位置爲空,則將值分配給位置並保存,否則不執行任何操作。
public void setLocation(String id, String location){
Member m = memberDao.find(id); // assume m is not null
if(null == m.getLocation()){
m.setLocation(location);
memeberDao.saveOrUpdate(m);
}
else
throw new MemberAlreadyHasALocationException();
}
刪除地點:
- 獲得基於ID從數據庫成員。
- 如果位置有一個非空值,電流值等於參數值,設置位置爲空和更新,否則什麼都不做
public void removeLocation(String id, String location){
Member m = memberDao.find(id);
if(m.getLocation() != null && m.getLocation.equalsIgnoreCase(location)){
m.setLocation(null);
memeberDao.saveOrUpdate(m);
}
}
我任務是處理併發性問題,但我不知道怎麼樣在休眠中做到這一點。更具體地說,我如何處理對同一ID的setLocation併發調用,因爲具有該ID的實體當前沒有位置。
基本上,第一次更新應該贏,第二次應該會失敗。
是否足以版本添加到成員類
@Version
@Column(name="version")
private Long version;
不過,說是有一個性別字段,我希望能夠在不關心更新性別字段,如果該位置被由另一個事務更新。
謝謝。
感謝您的信息。我想現在,從休眠狀態轉移,我只想給位置一個值,只有當它爲空時才允許併發。但是,我不想阻止每次調用setLocation,而是要阻止對特定成員id的setLocation調用,以便兩個不同成員的setLocation調用不會被阻止,而是兩次調用setLocation爲同一個成員做塊。我還沒有找到一個好方法來做到這一點,我喜歡:http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value – jsl 2011-04-28 14:18:06
只需使用一個存儲過程來檢查成員,如果他不存在,則返回-1,否則如果該成員確實存在並且他有一個位置,則返回0(不更新),否則更新該位置並返回1.數據庫是否會正確處理併發調用程序? – jsl 2011-04-28 14:22:16
@jsl你應該檢查一下Hibernate中的悲觀鎖定。這將允許一次只允許一個線程對實體進行更改,阻止其他人想要對同一個實體進行更改。但是,這也會阻止想要更新位置以外的其他屬性的線程 – 2011-04-28 16:21:23