吾非文人,乃市井一俗人也,讀百卷書(shū),跨江河千里,故申城一游; 一兩滴辛酸,三四年學(xué)業(yè),五六點(diǎn)粗墨,七八筆買(mǎi)賣(mài),九十道人情。
獲取數(shù)據(jù) query.setLockMode 對(duì)查詢(xún)語(yǔ)句中特定別名所對(duì)應(yīng)的記錄進(jìn)行加鎖(我們?yōu)?TUser類(lèi)指定了一個(gè)別名“user”),這里也就是對(duì)返回的所有user記錄進(jìn)行加鎖。 觀察運(yùn)行期Hibernate生成的SQL語(yǔ)句:
這里Hibernate通過(guò)使用數(shù)據(jù)庫(kù)的for update子句實(shí)現(xiàn)了悲觀鎖機(jī)制。 上面這兩種鎖機(jī)制是我們?cè)趹?yīng)用層較為常用的,加鎖一般通過(guò)以下方法實(shí)現(xiàn): Criteria.setLockMode Query.setLockMode Session.lock 注意,只有在查詢(xún)開(kāi)始之前(也就是Hiberate 生成SQL 之前)設(shè)定加鎖,才會(huì) 真正通過(guò)數(shù)據(jù)庫(kù)的鎖機(jī)制進(jìn)行加鎖處理,否則,數(shù)據(jù)已經(jīng)通過(guò)不包含for update 子句的Select SQL加載進(jìn)來(lái),所謂數(shù)據(jù)庫(kù)加鎖也就無(wú)從談起。
注意version 節(jié)點(diǎn)必須出現(xiàn)在ID 節(jié)點(diǎn)之后。 這里我們聲明了一個(gè)version屬性,用于存放用戶(hù)的版本信息,保存在TUser表的 version字段中。 此時(shí)如果我們嘗試編寫(xiě)一段代碼,更新TUser表中記錄數(shù)據(jù),如: 代碼內(nèi)容
每次對(duì)TUser進(jìn)行更新的時(shí)候,我們可以發(fā)現(xiàn),數(shù)據(jù)庫(kù)中的version都在遞增。 而如果我們嘗試在tx.commit 之前,啟動(dòng)另外一個(gè)Session,對(duì)名為Erica 的用 戶(hù)進(jìn)行操作,以模擬并發(fā)更新時(shí)的情形: 代碼內(nèi)容
執(zhí)行以上代碼,代碼將在tx.commit()處拋出StaleObjectStateException異 常,并指出版本檢查失敗,當(dāng)前事務(wù)正在試圖提交一個(gè)過(guò)期數(shù)據(jù)。通過(guò)捕捉這個(gè)異常,我 們就可以在樂(lè)觀鎖校驗(yàn)失敗時(shí)進(jìn)行相應(yīng)處理。
Powered by: BlogJava Copyright © 張金鵬