我在使用NHibernate異步保存到數據庫時遇到競爭條件問題。首先對數據庫的插入是異步完成的,其中唯一ID是自動生成的。在這個插入返回到主線程之前,這個持久化對象具有唯一的數據庫生成的id,該對象以某種方式更新。如果我調用session.Update,更新將失敗,因爲要更新的對象沒有id值。如果我調用SaveOrUpdate,它顯然會導致插入而不是更新,因爲我的實體的id字段等於unsaved-value屬性。希望這段代碼能夠使情況更加清晰:Nhibernate,多線程和競態條件
Entity entity = new Entity()
//update some fields
entity.PropertyTwo = "new value";
//dataObject as the database auto-generated Id
//insert new row asynchronously in different thread
Entity entity.Id = dao.save(entity.Clone()).Id
//before the the entity is returned from the database, the entity might be updated
entity.Property = 'new value';
//entity might be sent without an Id since the first asynch call has not returned yet.
//update asynchronously in another thread
Object dataObject = dao.Update(entity); //fails because Id is not set yet
一種解決方案是在保存之前在代碼中生成唯一的ID。在這種情況下,應用程序管理唯一標識的增量,而不是數據庫。任何其他方式處理這個?
不,我正在爲每個線程創建一個會話。如果在插入完成之前在實體上更新更新 – infinity 2009-11-24 18:56:17
記住每個數據庫調用都發生在另一個線程上,所以如果在第二個線程上嘗試更新,然後插入在前一個線程上完成,則會出現競態條件錯誤。 – infinity 2009-11-24 19:02:12
你能解釋爲什麼你要克隆實體對象並保存克隆?你可能已經試過了,但是如果你在同一個實體對象(無克隆)的所有線程中執行SaveOrUpdate(),那麼無論哪個線程首先插入,其他線程都會執行更新。這是否適合您的設計? – 2009-11-24 21:52:01