很多程序需要在某个事务中获取对象,然后将对象发送到界面层去操作,最后在一个新的事务保存所做的修改。 在高并发访问的环境中使用这种方式,通常使用附带版本信息的数据来保证这些“长“工作单元之间的隔离。
Hibernate通过提供使用Session.update()或Session.merge()方法 重新关联脱管实例的办法来支持这种模型。
// in the first session
Cat cat = (Cat) firstSession.load(Cat.class, catId);
Cat potentialMate = new Cat();
firstSession.save(potentialMate);
// in a higher layer of the application
cat.setMate(potentialMate);
// later, in a new session
secondSession.update(cat); // update cat
secondSession.update(mate); // update mate
如果具有catId持久化标识的Cat之前已经被另一Session(secondSession)装载了, 应用程序进行重关联操作(reattach)的时候会抛出一个异常。
如果你确定当前session没有包含与之具有相同持久化标识的持久实例,使用update()。 如果想随时合并你的的改动而不考虑session的状态,使用merge()。 换句话说,在一个新session中通常第一个调用的是update()方法,以便保证重新关联脱管(detached)对象的操作首先被执行。
希望相关联的脱管对象(通过引用“可到达”的脱管对象)的数据也要更新到数据库时(并且也仅仅在这种情况), 应用程序需要对该相关联的脱管对象单独调用update() 当然这些可以自动完成,即通过使用传播性持久化(transitive persistence),请看第 11.11 节 “传播性持久化(transitive persistence)”。
lock()方法也允许程序重新关联某个对象到一个新session上。不过,该脱管(detached)的对象必须是没有修改过的!
//just reassociate:
sess.lock(fritz, LockMode.NONE);
//do a version check, then reassociate:
sess.lock(izi, LockMode.READ);
//do a version check, using SELECT ... FOR UPDATE, then reassociate:
sess.lock(pk, LockMode.UPGRADE);
请注意,lock()可以搭配多种LockMode, 更多信息请阅读API文档以及关于事务处理(transaction handling)的章节。重新关联不是lock()的唯一用途。
其他用于长时间工作单元的模型会在第 12.3 节 “乐观并发控制(Optimistic concurrency control)”中讨论。
文章出处:http://docs.huihoo.com/framework/hibernate/reference-v3_zh-cn/objectstate.html
posted on 2007-10-29 16:15
Ke 阅读(326)
评论(0) 编辑 收藏 所属分类:
hibernate