1. 程式人生 > >數據庫行鎖,表鎖

數據庫行鎖,表鎖

開始 mode 由於 一個數 table 並且 增刪改 又能 對數

鎖主要用於多用戶環境下保證數據庫完整性和一致性。 我們知道,多個用戶能夠同時操縱同一個數據庫中的數據,會發生數據不一致現象。即如果沒有鎖定且多個用戶同時訪問一個數據庫,則當他們的事務同時使用相同的數據時可能會發生問題。這些問題包括:臟讀、不可重復讀和幻讀

臟讀就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。因為這個數據是還沒有提交的數據,那麽另外一個事務讀到的這個數據是臟數據,依據臟數據所做的操作可能是不正確的。(解決辦法:Read Committed 讀提交,保證只有當A事務提交了數據之後,B事務才能夠讀取數據)

不可重復讀是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據並提交。那麽,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那麽第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。(解決辦法:加行鎖,A事務在操作某幾行數據的時候,B事務只能操作其他行的數據,加鎖了的幾行無法進行操作,這樣就避免了兩次讀的不一致性。Mysql默認使用這種方法。 Repeatable Read可重復讀)

幻讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麽,就會發生第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。(解決辦法:只能對整個表加鎖,開銷最小,但是性能最低。 Serializable串行化)

Read Uncommitted 不能避免臟讀、不可重復讀和幻讀。

--------------------------------------------------------------------------------------------------------------

行級鎖是Mysql中鎖定粒度最細的一種鎖,行級鎖能大大減少數據庫操作的沖突。行級鎖分為共享鎖和排他鎖兩種,本文將詳細介紹共享鎖及排他鎖的概念、使用方式及註意事項等。

共享鎖(Share Lock)

共享鎖又稱讀鎖,是讀取操作創建的鎖。其他用戶可以並發讀取數據,但任何事務都不能對數據進行修改(獲取數據上的排他鎖),直到已釋放所有共享鎖。

如果事務T對數據A加上共享鎖後,則其他事務只能對A再加共享鎖,不能加排他鎖。獲準共享鎖的事務只能讀數據,不能修改數據。

用法

SELECT ... LOCK IN SHARE MODE;

在查詢語句後面增加LOCK IN SHARE MODE,Mysql會對查詢結果中的每行都加共享鎖,當沒有其他線程對查詢結果集中的任何一行使用排他鎖時,可以成功申請共享鎖,否則會被阻塞。其他線程也可以讀取使用了共享鎖的表,而且這些線程讀取的是同一個版本的數據。

排他鎖(eXclusive Lock)

排他鎖又稱寫鎖,如果事務T對數據A加上排他鎖後,則其他事務不能再對A加任任何類型的封鎖。獲準排他鎖的事務既能讀數據,又能修改數據。

用法

SELECT ... FOR UPDATE;

在查詢語句後面增加FOR UPDATE,Mysql會對查詢結果中的每行都加排他鎖,當沒有其他線程對查詢結果集中的任何一行使用排他鎖時,可以成功申請排他鎖,否則會被阻塞。

對於insert、update、delete(增刪改),InnoDB會自動給涉及的數據加排他鎖(X);對於一般的Select語句,InnoDB不會加任何鎖。

在mysql中有表鎖,

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

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

-----------------------------------------------------------------------------------------------------------------

意向鎖的作用就是“表明”加鎖的意圖: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。

意向鎖是表級鎖,InnoDB中的兩個表鎖:

意向共享鎖(IS):表示事務準備給數據行加入共享鎖,也就是說給一個數據行加共享鎖前必須先取得該表的IS鎖

意向排他鎖(IX):類似上面,表示事務準備給數據行加入排他鎖,也就是說事務在一個數據行加排他鎖前必須先取得該表的IX鎖。

意向鎖是InnoDB自動加的,不需要用戶幹預。

IX,IS是表級鎖,不會和行級的X,S鎖發生沖突。只會和表級的X,S發生沖突

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

考慮這個例子:

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

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

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

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

數據庫要怎麽判斷這個沖突呢?

step1:判斷表是否已被其他事務用表鎖鎖表
step2:判斷表中的每一行是否已被行鎖鎖住。

註意step2,這樣的判斷方法效率實在不高,因為需要遍歷整個表。
於是就有了意向鎖。

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

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

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


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

---------------------------------------------------------------------------------------------------------------






數據庫行鎖,表鎖