MySQL技術內幕 七:鎖(包括樂觀悲觀鎖)(已遷移)

一:鎖:

        鎖是數據庫系統區別於文件系統的一個關鍵特性,鎖機制用於管理對共享資源的併發訪問。InnoDB存儲引擎會在行級別上對錶數據上鎖,不過在數據庫內部其他地方也使用鎖,從而允許對多種不同資源提供併發訪問。例如,操作緩衝池中的LRU列表,刪除。添加。移動LRU列表中的元素,爲了保證一致性,必須有鎖介入。鎖是爲了支持對共享資源的併發訪問。innodb不需要鎖升級,因爲一個鎖和多個鎖的開銷是相同的

    InnoDB存儲引擎鎖的實現和oracle非常類似,提供一致性的非鎖定讀。行級鎖支持,行級鎖沒有相關的開銷,可以同時得到併發性和一致性

innodb

二:鎖的類型:

        1.共享鎖(S Lock),允許事務讀(同)一行數據。

        2.排他鎖(X Lock),允許事務刪除或者更新一行數據。

        理解:當一個事務已經獲得行r的共享鎖,那麼另外的事務可以立即獲得行r的共享鎖,因爲讀取並沒有改變行r的數據,我們稱這種情況爲鎖兼容。但如果有事務想獲得行r的排他鎖,必須等待事務釋放行r的共享鎖---------這種情況稱爲鎖不兼容

三:一致性的非鎖定讀操作:

    一致性的非鎖定行讀是指InnoDB存儲引擎通過多版本併發控制(MVCC)的方式來讀取當前執行時間數據庫中行的數據。如果讀取得行正在執行delete/update操作,這時讀取操作不會因此而會等待行上鎖的釋放,相反,InnoDB會去讀取行的一個快照數據。正是因爲不需要等待訪問的行上x鎖的釋放,快照數據是指該行之前版本的數據。通過undo段實現,而undo段用來在事務中回滾數據,因此快照數據本身沒有額外開銷,不需上鎖

    理解:對於一致性的非鎖定讀的快照數據是之前版本的數據,不一定是最新的數據,對於快照數據的定義有幾種,一種是最新數據

四:行鎖與表鎖比較:

       1.表鎖:是最基本的鎖策略,開銷最小,對整張表進行鎖定,寫鎖的優先級比讀鎖高,寫鎖可以插入到讀鎖的隊列前面,反之則不行。一個用戶在對錶進行寫操作時(插入、更新、刪除等),需要先獲得寫鎖,這會阻塞其他用戶對該表的所有讀寫操作,只有沒有寫鎖時,其他用戶才能得到讀鎖。

       2.行鎖:可以最大程度的支持併發(鎖定的資源最少),只在存儲引擎層實現,而在mysql服務器層沒有實現,服務器會爲alter table 使用表鎖,而忽略存儲引擎的鎖機制

五:樂觀鎖與悲觀鎖:

       悲觀鎖,也叫悲觀併發控制,當事務A對某行數據應用了鎖,並且當這個事務把鎖釋放後,其他事務才能夠執行與該鎖衝突的操作,這裏事務A所施加的鎖就叫悲觀鎖。

看到這裏,會發現,我們之前學習的共享鎖和排他鎖(行鎖,間隙鎖,next-key lock)都屬於悲觀鎖。

      樂觀鎖,也叫樂觀併發控制,它假設多用戶併發的事務在處理時不會彼此互相影響,各事務能夠在不產生鎖的情況下處理各自影響的那部分數據。在提交數據更新之前,每個事務會先檢查在該事務讀取數據後,有沒有其他事務又修改了該數據。如果其他事務有更新的話,那麼當前正在提交的事務會進行回滾。
悲觀鎖的實現依靠的是數據庫提供的鎖機制來實現,例如select * from news where id=12 for update,而樂觀鎖依靠的是記錄數據版本來實現,即通過在表中添加版本號字段來作爲是否可以成功提交的關鍵因素。

根據之前對鎖的學習,我們可以大概可以看到innodb下各個鎖之間的關係,如圖:


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章