很多程序需要在某個(gè)事務(wù)中獲取對(duì)象,然后將對(duì)象發(fā)送到界面層去操作,最后在一個(gè)新的事務(wù)保存所做的修改。 在高并發(fā)訪問(wèn)的環(huán)境中使用這種方式,通常使用附帶版本信息的數(shù)據(jù)來(lái)保證這些“長(zhǎng)“工作單元之間的隔離。
Hibernate通過(guò)提供使用Session.update()或Session.merge()方法 重新關(guān)聯(lián)脫管實(shí)例的辦法來(lái)支持這種模型。
// 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持久化標(biāo)識(shí)的Cat之前已經(jīng)被另一Session(secondSession)裝載了, 應(yīng)用程序進(jìn)行重關(guān)聯(lián)操作(reattach)的時(shí)候會(huì)拋出一個(gè)異常。
如果你確定當(dāng)前session沒(méi)有包含與之具有相同持久化標(biāo)識(shí)的持久實(shí)例,使用update()。 如果想隨時(shí)合并你的的改動(dòng)而不考慮session的狀態(tài),使用merge()。 換句話說(shuō),在一個(gè)新session中通常第一個(gè)調(diào)用的是update()方法,以便保證重新關(guān)聯(lián)脫管(detached)對(duì)象的操作首先被執(zhí)行。
希望相關(guān)聯(lián)的脫管對(duì)象(通過(guò)引用“可到達(dá)”的脫管對(duì)象)的數(shù)據(jù)也要更新到數(shù)據(jù)庫(kù)時(shí)(并且也僅僅在這種情況), 應(yīng)用程序需要對(duì)該相關(guān)聯(lián)的脫管對(duì)象單獨(dú)調(diào)用update() 當(dāng)然這些可以自動(dòng)完成,即通過(guò)使用傳播性持久化(transitive persistence),請(qǐng)看第 11.11 節(jié) “傳播性持久化(transitive persistence)”。
lock()方法也允許程序重新關(guān)聯(lián)某個(gè)對(duì)象到一個(gè)新session上。不過(guò),該脫管(detached)的對(duì)象必須是沒(méi)有修改過(guò)的!
//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);
請(qǐng)注意,lock()可以搭配多種LockMode, 更多信息請(qǐng)閱讀API文檔以及關(guān)于事務(wù)處理(transaction handling)的章節(jié)。重新關(guān)聯(lián)不是lock()的唯一用途。
其他用于長(zhǎng)時(shí)間工作單元的模型會(huì)在第 12.3 節(jié) “樂(lè)觀并發(fā)控制(Optimistic concurrency control)”中討論。
文章出處:http://docs.huihoo.com/framework/hibernate/reference-v3_zh-cn/objectstate.html