我在使用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