innodb的意向鎖有什麼作用?

mysql官網上對於意向鎖的解釋中有這麼一句話「The main purpose of IX and IS locks is to show that someone is locking a row, or going to lock a row in the table.」意思是說加意向鎖的目的是為了表明某個事務正在鎖定一行或者將要鎖定一行。那麼,意向鎖的作用就是「表明」加鎖的意圖,可是為什麼要表明這個 意圖呢?如果僅僅鎖定一行僅僅需要加一個鎖,那麼就直接加鎖就好了,這裡要表明加鎖意圖的原因是因為要鎖定一行不僅僅是要加一個鎖,而是要做一系列操作嗎?


我最近也在看這個,我說一下我的理解

①在mysql中有表鎖,

LOCK TABLE my_tabl_name READ; 用讀鎖鎖表,會阻塞其他事務修改表數據。

LOCK TABLE my_table_name WRITe; 用寫鎖鎖表,會阻塞其他事務讀和寫。

②Innodb引擎又支持行鎖,行鎖分為

共享鎖,一個事務對一行的共享只讀鎖。

排它鎖,一個事務對一行的排他讀寫鎖。

③這兩中類型的鎖共存的問題

考慮這個例子:

事務A鎖住了表中的一行,讓這一行只能讀,不能寫。

之後,事務B申請整個表的寫鎖。

如果事務B申請成功,那麼理論上它就能修改表中的任意一行,這與A持有的行鎖是衝突的。

資料庫需要避免這種衝突,就是說要讓B的申請被阻塞,直到A釋放了行鎖。

資料庫要怎麼判斷這個衝突呢?

step1:判斷表是否已被其他事務用表鎖鎖表

step2:判斷表中的每一行是否已被行鎖鎖住。

注意step2,這樣的判斷方法效率實在不高,因為需要遍歷整個表。

於是就有了意向鎖。

在意向鎖存在的情況下,事務A必須先申請表的意向共享鎖,成功後再申請一行的行鎖。

在意向鎖存在的情況下,上面的判斷可以改成

step1:不變

step2:發現表上有意向共享鎖,說明表中有些行被共享行鎖鎖住了,因此,事務B申請表的寫鎖會被阻塞。

注意:申請意向鎖的動作是資料庫完成的,就是說,事務A申請一行的行鎖的時候,資料庫會自動先開始申請表的意向鎖,不需要我們程序員使用代碼來申請。


一直以來的困惑是,IX 與 X衝突,那豈不是任意兩個寫操作,即使寫不同行也會造成死鎖

  1. Session A 請求 IX--成功,Session B請求 IX--成功
  2. Session A 請求 X,發現已經有其他session有IX,因此衝突
  3. 同理SessionB請求X也會是這種情況。那這row lock還有什麼用?

Google了好久,找到了一個讓自己滿意的解釋。原來我自己的理解有偏差

Reference:http://www.slideshare.net/billkarwin/innodb-locking-explained-with-stick-figures

核心在於兩句話:

IS and IX locks allow access by multiple clients. They won"t necessarily conflict until they try to get real locks on the same rows.

But a table lock (ALTER TABLE, DROP TABLE, LOCK TABLES) blocks both IS and IX, and vice-versa.

總結一下就是:

  • IX,IS是表級鎖,不會和行級的X,S鎖發生衝突。只會和表級的X,S發生衝突
  • 行級別的X和S按照普通的共享、排他規則即可。所以之前的示例中第2步不會衝突,只要寫操作不是同一行,就不會發生衝突。

解決完這個疑問,再來回答意向鎖的作用。意向鎖是在添加行鎖之前添加。

當再向一個表添加表級X鎖的時候

  • 如果沒有意向鎖的話,則需要遍歷所有整個表判斷是否有行鎖的存在,以免發生衝突
  • 如果有了意向鎖,只需要判斷該意向鎖與即將添加的表級鎖是否兼容即可。因為意向鎖的存在代表了,有行級鎖的存在或者即將有行級鎖的存在。因而無需遍歷整個表,即可獲取結果


為了實現多粒度鎖機制(白話:為了表鎖和行鎖都能用)

補充一句:

意向鎖是表鎖


推薦閱讀:

如果從頭開始,如何少走彎路成為合格的DBA?
目前的資料庫管理認證都有哪些呢?Oracle、DB2、MS SQL、MySQL都分別有哪些認證呢??
面向主題的資料庫技術的概念已經提出十幾年了,理念是先進的,但為什麼被實際應用很少?
自己做個erp系統,目前主流的開發軟體是什麼?

TAG:資料庫 | MySQL | InnoDB |