oracle的讀鎖

我們有時(shí)候要對(duì)讀出的數(shù)據(jù)做變更,如果使用常規(guī)的select讀出來(lái),再u(mài)pdate,那么可能在update之前,其他的事務(wù)對(duì)所讀的數(shù)據(jù)做了修改,這時(shí)我們之前讀到的數(shù)據(jù)就變成了臟數(shù)據(jù)。針對(duì)這種需求,oracle提供了兩者類(lèi)型的讀鎖:

  1. 共享讀鎖

SELECT ... LOCK IN SHARE MODE

  • 使用共享鎖讀數(shù)據(jù),其他的事務(wù)也能對(duì)這些數(shù)據(jù)執(zhí)行讀操作。但只能等到共享鎖讀事務(wù)提交后才能執(zhí)行修改操作。

  • 如果在共享鎖讀之前,其他的事務(wù)正在對(duì)這些數(shù)據(jù)做更新,則當(dāng)前的讀操作會(huì)等其他事務(wù)結(jié)束后,再讀最新的數(shù)據(jù)來(lái)做修改。

  • 事務(wù)提交后,共享鎖才會(huì)被釋放。

  • 共享鎖一般在不互斥讀的場(chǎng)景下使用,即對(duì)讀的要求不嚴(yán)格。比如child表,主鍵用一個(gè)counter的變量通過(guò)遞增的方式生成,如果使用共享鎖,則兩個(gè)會(huì)話讀到的數(shù)據(jù)可能會(huì)一致,這會(huì)導(dǎo)致提交的修改也會(huì)一致,結(jié)果會(huì)導(dǎo)致主鍵沖突。

2.互斥讀鎖

SELECT ... FOR UPDATE

  • 互斥讀鎖會(huì)鎖住符合條件的行,以及與其相關(guān)的索引列表,跟我們使用update語(yǔ)句對(duì)這些行做操作一樣。

  • 其他事務(wù)在這些行上的更新操作將會(huì)被阻塞,如共享讀更新,或者某些隔離級(jí)別的讀更新事務(wù)。

  • 互斥讀鎖只有在使用事務(wù)( START TRANSACTION ),或者關(guān)閉自動(dòng)提交(將autocommit設(shè)為0)的情況下才起作用。否則如果允許自動(dòng)提交,使用互斥讀鎖時(shí)符合條件的行不會(huì)被鎖。

針對(duì)上面那種情況,我試了下不在方法上開(kāi)啟(annotation方式)spring的聲明式事務(wù),使用互斥讀鎖也能鎖到符合條件的行,使用hibernate的upgrade_wait lock_mode,但方法結(jié)束后鎖并未被釋放,如果SELECT ... FOR UPDATE的后面緊接著使用 UPDATE ... SET ...更新這些數(shù)據(jù),則會(huì)造成死鎖。為什么會(huì)出現(xiàn)這種情況,目前還未找到原因。

參考資料:
官方文檔 SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容