mysql鎖能在并發情況下的mysql進行更好的優化
MySQL有三種鎖的級別:頁級、表級、行級,這3種鎖的特性可大致歸納如下:
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,并發度最低。
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,并發度也最高。
頁面鎖:開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間,并發度一般。
由于InnoDB預設是Row-Level Lock,所以只有「明確」的指定主鍵,MySQL才會執行Row lock (只鎖住被選取的資料例) ,否則MySQL將會執行Table Lock (將整個資料表單給鎖住)。
舉個例子:
假設有個表單products ,里面有id跟name二個欄位,id是主鍵。
例1: (明確指定主鍵,并且有此筆資料,row lock)
SELECT * FROM products WHERE id='3' FOR UPDATE;
SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;
例2: (明確指定主鍵,若查無此筆資料,無lock)
SELECT * FROM products WHERE id='-1' FOR UPDATE;
例2: (無主鍵,table lock)
SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
例3: (主鍵不明確,table lock)
SELECT * FROM products WHERE id<>'3' FOR UPDATE;
例4: (主鍵不明確,table lock)
SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;
注1: FOR UPDATE僅適用于InnoDB,且必須在交易區塊(BEGIN/COMMIT)中才能生效。
注2: 要測試鎖定的狀況,可以利用MySQL的Command Mode ,開二個視窗來做測試。
在MySql 5.0中測試確實是這樣的
另外:MyAsim 只支持表級鎖,InnerDB支持行級鎖
添加了(行級鎖/表級鎖)鎖的數據不能被其它事務再鎖定,也不被其它事務修改(修改、刪除)
是表級鎖時,不管是否查詢到記錄,都會鎖定表
死鎖:
什么是死鎖,在網上摘抄一段通俗的說法:
老板要你做個事情,然后老板在等你做好后匯報結果給他。然后,現在你去忙這件事情了。在你還沒做完這件事的時候,你的老板想再次的叫你做另一件事,于是,他到你的辦公室找你,而你這時候已經做完前面的事情去了老板的辦公室想匯報結果。你們兩看到對方不在辦公室,就在對方辦公室一直等待,那么你就無法等到老板,你的老板也等不到你,這樣就死鎖了。
解決辦法,1、一般解決這樣的情況,就是增加一個秘書,你開始做什么事情了。是否結束了。他都有記錄。老板要下達命令前,先詢問秘書就可以了。如果你正在忙,就稍微的等一會。這就是類似的情況。秘書相當于線程互斥的對象,用于同步兩個線程。2、首先你要給線程(你自己一個手機,或者秘書) 然后盡量監測自己的狀態是否死鎖了。
外圍管理線程(你的老板也要有辦法聯系你,比如給你打電話)給你的消息隊列插命令、 或者檢查你執行了多少時間或者循環次數。是在不行就吧你殺了,再招一個工人
那么現在看看mysql的死鎖:如果A與B都對表id進行查詢但查詢不到記錄,則A與B在查詢上不會進行row鎖,但A與B都會獲取排它鎖,此時A再插入一條記錄的話則會因為B已
經有鎖而處于等待中,此時B再插入一條同樣的數據則會拋出
Deadlock found when trying to get lock; try restarting transaction然后釋放鎖,
此時A就獲得了鎖而插入成功
相關:
mysql的鎖表問題
通過mysql show processlist 命令檢查mysql鎖的方法
文章列表