MyISAM和InnoDB存儲(chǔ)引擎使用的鎖:
創(chuàng)新互聯(lián)是一家以網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、品牌設(shè)計(jì)、軟件運(yùn)維、seo優(yōu)化、小程序App開(kāi)發(fā)等移動(dòng)開(kāi)發(fā)為一體互聯(lián)網(wǎng)公司。已累計(jì)為成都履帶攪拌車(chē)等眾行業(yè)中小客戶提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開(kāi)發(fā)服務(wù)。
封鎖粒度?。?/p>
由于InnoDB存儲(chǔ)引擎支持的是行級(jí)別的鎖,因此意向鎖(因?yàn)橐庀蜴i是表鎖)其實(shí)不會(huì)阻塞除全表掃以外的任何請(qǐng)求。故表級(jí)意向鎖與行級(jí)鎖的兼容性如下所示
參考
參考
行鎖的三種算法:
這條語(yǔ)句阻止其他事務(wù)插入10和20之間的數(shù)字,無(wú)論這個(gè)數(shù)字是否存在。 間隙可以跨越0個(gè),單個(gè)或多個(gè)索引值。
共享鎖:
排他鎖:
樂(lè)觀鎖:總是假設(shè)最好的情況,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改(天真), 操作數(shù)據(jù)時(shí)不會(huì)上鎖 ,但是 更新時(shí)會(huì)判斷在此期間有沒(méi)有別的事務(wù)更新這個(gè)數(shù)據(jù),若被更新過(guò),則失敗重試 ;適用于讀多寫(xiě)少的場(chǎng)景。
樂(lè)觀鎖的實(shí)現(xiàn)方式 有:
關(guān)閉自動(dòng)提交后,我們需要手動(dòng)開(kāi)啟事務(wù)。
上述就實(shí)現(xiàn)了悲觀鎖,悲觀鎖就是悲觀主義者,它會(huì)認(rèn)為我們?cè)谑聞?wù)A中操作數(shù)據(jù)1的時(shí)候,一定會(huì)有事務(wù)B來(lái)修改數(shù)據(jù)1,所以,在第2步我們將數(shù)據(jù)查詢出來(lái)后直接加上排它鎖(X)鎖,防止別的事務(wù)來(lái)修改事務(wù)1,直到我們commit后,才釋放了排它鎖。
悲觀鎖就是數(shù)據(jù)庫(kù)里面鎖住 類(lèi)似for update查詢
樂(lè)觀鎖不是在數(shù)據(jù)庫(kù)端鎖住的
而是程序控制的
你說(shuō)的那Mybatis我不知道是什么
但是樂(lè)觀鎖一般是這樣
比如你數(shù)據(jù)庫(kù)中有一條記錄
你可以給他加上一個(gè)版本號(hào)
這樣
如果同時(shí)有2個(gè)人查詢出那個(gè)數(shù)據(jù)要修改
第一個(gè)人先查出來(lái)有事走了
第二個(gè)人查出來(lái)給改了
這時(shí)候你看
第一個(gè)人查出來(lái)的數(shù)據(jù)版本號(hào)比如是1
第二個(gè)人查出來(lái)也是1 但是他改了數(shù)據(jù)以后版本號(hào)變成2
這時(shí)候第一個(gè)人回來(lái)了繼續(xù)修改數(shù)據(jù)
他的版本號(hào)是1 比2低
這時(shí)候就告訴他數(shù)據(jù)過(guò)期
樂(lè)觀鎖大概就是這個(gè)意思
是一種思路!
關(guān)于mysql中的樂(lè)觀鎖和悲觀鎖面試的時(shí)候被問(wèn)到的概率還是比較大的。
mysql的悲觀鎖:
其實(shí)理解起來(lái)非常簡(jiǎn)單,當(dāng)數(shù)據(jù)被外界修改持保守態(tài)度,包括自身系統(tǒng)當(dāng)前的其他事務(wù),以及來(lái)自外部系統(tǒng)的事務(wù)處理,因此,在整個(gè)數(shù)據(jù)處理過(guò)程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制,但是也只有數(shù)據(jù)庫(kù)層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪問(wèn)的排他性,否則,即使在自身系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無(wú)法保證外部系統(tǒng)不會(huì)修改數(shù)據(jù)。
來(lái)點(diǎn)實(shí)際的,當(dāng)我們使用悲觀鎖的時(shí)候我們首先必須關(guān)閉mysql數(shù)據(jù)庫(kù)的自動(dòng)提交屬性,因?yàn)镸ySQL默認(rèn)使用autocommit模式,也就是說(shuō),當(dāng)你執(zhí)行一個(gè)更新操作后,MySQL會(huì)立刻將結(jié)果進(jìn)行提交。
關(guān)閉命令為:set autocommit=0;
悲觀鎖可以使用select…for update實(shí)現(xiàn),在執(zhí)行的時(shí)候會(huì)鎖定數(shù)據(jù),雖然會(huì)鎖定數(shù)據(jù),但是不影響其他事務(wù)的普通查詢使用。此處說(shuō)普通查詢就是平時(shí)我們用的:select * from table 語(yǔ)句。在我們使用悲觀鎖的時(shí)候事務(wù)中的語(yǔ)句例如:
//開(kāi)始事務(wù)
begin;/begin work;/start transaction; (三選一)
//查詢信息
select * from order where id=1 for update;
//修改信息
update order set name='names';
//提交事務(wù)
commit;/commit work;(二選一)
此處的查詢語(yǔ)句for update關(guān)鍵字,在事務(wù)中只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一條數(shù)據(jù)時(shí)會(huì)等待其它事務(wù)結(jié)束后才執(zhí)行,一般的SELECT查詢則不受影響。
執(zhí)行事務(wù)時(shí)關(guān)鍵字select…for update會(huì)鎖定數(shù)據(jù),防止其他事務(wù)更改數(shù)據(jù)。但是鎖定數(shù)據(jù)也是有規(guī)則的。
查詢條件與鎖定范圍:
1、具體的主鍵值為查詢條件
比如查詢條件為主鍵ID=1等等,如果此條數(shù)據(jù)存在,則鎖定當(dāng)前行數(shù)據(jù),如果不存在,則不鎖定。
2、不具體的主鍵值為查詢條件
比如查詢條件為主鍵ID1等等,此時(shí)會(huì)鎖定整張數(shù)據(jù)表。
3、查詢條件中無(wú)主鍵
會(huì)鎖定整張數(shù)據(jù)表。
4、如果查詢條件中使用了索引為查詢條件
明確指定索引并且查到,則鎖定整條數(shù)據(jù)。如果找不到指定索引數(shù)據(jù),則不加鎖。
悲觀鎖的確保了數(shù)據(jù)的安全性,在數(shù)據(jù)被操作的時(shí)候鎖定數(shù)據(jù)不被訪問(wèn),但是這樣會(huì)帶來(lái)很大的性能問(wèn)題。因此悲觀鎖在實(shí)際開(kāi)發(fā)中使用是相對(duì)比較少的。
mysql的樂(lè)觀鎖:
相對(duì)悲觀鎖而言,樂(lè)觀鎖假設(shè)數(shù)據(jù)一般情況下不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會(huì)對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測(cè),如果發(fā)現(xiàn)沖突,則讓返回用戶錯(cuò)誤的信息,讓用戶決定如何去做。
一般來(lái)說(shuō),實(shí)現(xiàn)樂(lè)觀鎖的方法是在數(shù)據(jù)表中增加一個(gè)version字段,每當(dāng)數(shù)據(jù)更新的時(shí)候這個(gè)字段執(zhí)行加1操作。這樣當(dāng)數(shù)據(jù)更改的時(shí)候,另外一個(gè)事務(wù)訪問(wèn)此條數(shù)據(jù)進(jìn)行更改的話就會(huì)操作失敗,從而避免了并發(fā)操作錯(cuò)誤。當(dāng)然,還可以將version字段改為時(shí)間戳,不過(guò)原理都是一樣的。
例如有表student,字段:
id,name,version
1 a 1
當(dāng)事務(wù)一進(jìn)行更新操作:update student set name='ygz' where id = #{id} and version = #{version};
此時(shí)操作完后數(shù)據(jù)會(huì)變?yōu)閕d = 1,name = ygz,version = 2,當(dāng)另外一個(gè)事務(wù)二同樣執(zhí)行更新操作的時(shí)候,卻發(fā)現(xiàn)version != 1,此時(shí)事務(wù)二就會(huì)操作失敗,從而保證了數(shù)據(jù)的正確性。
悲觀鎖和樂(lè)觀鎖都是要根據(jù)具體業(yè)務(wù)來(lái)選擇使用,本文僅作簡(jiǎn)單介紹。
以上不是重點(diǎn),重點(diǎn)是 對(duì)事務(wù)控制語(yǔ)句不熟悉。
SAVEPOINT identifier : 在事務(wù)中 創(chuàng)建保存點(diǎn)。一個(gè)事務(wù)中 允許有多個(gè)保存點(diǎn)。
RELEASE SAVEPOINT identifier : 刪除保存點(diǎn)。當(dāng)事務(wù)中 沒(méi)有指定的 保存點(diǎn),執(zhí)行該語(yǔ)句 會(huì)拋異常。
ROLLBACK TO identifier : 把事務(wù)回滾到 保存點(diǎn)。
Say you have a table T with a column C with one row in it, say it has the value '1'. And consider you have a simple task like following:
That is a simple task that issue two reads from table T, with a delay of 1 minute between them.
If you follow the logic above you can quickly realize that SERIALIZABLE transactions, while they may make life easy for you, are always completely blocking every possible concurrent operation, since they require that nobody can modify, delete nor insert any row. The default transaction isolation level of the .Net System.Transactions scope is serializable, and this usually explains the abysmal performance that results.
在Repeatable Read隔離級(jí)別下,一個(gè)事務(wù)可能會(huì)遇到幻讀(Phantom Read)的問(wèn)題。
幻讀是指,在一個(gè)事務(wù)中,第一次查詢某條記錄,發(fā)現(xiàn)沒(méi)有,但是,當(dāng)試圖更新這條不存在的記錄時(shí),竟然能成功,并且,再次讀取同一條記錄,它就神奇地出現(xiàn)了。
我們?nèi)匀幌葴?zhǔn)備好students表的數(shù)據(jù):
然后,分別開(kāi)啟兩個(gè)MySQL客戶端連接,按順序依次執(zhí)行事務(wù)A和事務(wù)B:
事務(wù)B在第3步第一次讀取id=99的記錄時(shí),讀到的記錄為空,說(shuō)明不存在id=99的記錄。隨后,事務(wù)A在第4步插入了一條id=99的記錄并提交。事務(wù)B在第6步再次讀取id=99的記錄時(shí),讀到的記錄仍然為空,但是,事務(wù)B在第7步試圖更新這條不存在的記錄時(shí),竟然成功了,并且,事務(wù)B在第8步再次讀取id=99的記錄時(shí),記錄出現(xiàn)了。
可見(jiàn),幻讀就是沒(méi)有讀到的記錄,以為不存在,但其實(shí)是可以更新成功的,并且,更新成功后,再次讀取,就出現(xiàn)了。
在沖突較少的情況下,使用樂(lè)觀鎖。樂(lè)觀鎖 因?yàn)闆](méi)有 加鎖 釋放鎖,也減少了 加鎖 釋放鎖的開(kāi)銷(xiāo)。
沖突較多時(shí),如果使用樂(lè)觀鎖 需要不停地嘗試,所以 使用悲觀鎖。
如果樂(lè)觀鎖 進(jìn)行嘗試時(shí) 的花銷(xiāo)較大,也是使用悲觀鎖。
網(wǎng)站標(biāo)題:mysql怎么加悲觀鎖,mysql 悲觀鎖 詳細(xì)講解
網(wǎng)站網(wǎng)址:http://aaarwkj.com/article0/dssgooo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、小程序開(kāi)發(fā)、ChatGPT、響應(yīng)式網(wǎng)站、動(dòng)態(tài)網(wǎng)站、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)