1. 程式人生 > >mysql中隔離級別和鎖有什麼關係?

mysql中隔離級別和鎖有什麼關係?

事務隔離級別,我將它理解為多執行緒資料隔離級別。大家可以想象一個物件有對其中某個欄位的增刪改查方法,在多執行緒的情況下就有很多種解決方案。

第一種:讀寫都是直接操作該欄位,不加同步鎖。

第二種:讀是操作該欄位的副本,寫是直接操作該欄位,不加同步鎖。

第三種:讀和寫都是操作該欄位的副本,不加同步鎖。

第四種:讀寫直接操作該欄位,加同步鎖。

ps:如果有副本,增刪改查都是操作副本

通用方法:commit,將副本資料同步至該欄位。

通用方法:rollback,將此事務所有操作了該欄位的方法回滾。

於是這類方法,便為分為了四類,分別為讀未提交,讀已提交,可重複讀,序列(中文理解,非要用英文,我手機也打不出來)

那麼現在開始簡單介紹四類隔離級別。

1:讀未提交,首先我們開啟兩個事務,分別為事務A和B,在事務A中更新刪除或修改一條資料後,在未commit的情況下,在事務B中可以直接查出來。也就是說事務B是讀取的資料而非副本,事務A是操作的資料而非副本。而rollback是將資料還原為事務A在開啟時的資料。

2:讀已提交,我們同樣用A和B,在事務A中更新刪除或修改一條資料後,在未commit的情況下,在事務B中查詢不到,在commit的情況下,在事務B中可以查詢到。也就是說事務B仍然是讀取的資料而非副本,事務A操作的是副本,commit的方法是將副本同步至資料。而rollback是將副本還原至事務A在開啟時的副本資料。

3:可重複讀,還是A和B,在事務A中更新刪除或修改一條資料後,在commit的情況下,在事務B中仍然查詢不到。也就是說事務B讀取的是資料的副本,當然事務A操作的也是副本。這點可以開事務C來驗證,將事務C的隔離級別調整為讀未提交即可。(大夥可自行驗證)

4:序列,所有事務操作序列,也就是事務A沒結束的時候,事務B開始也是等待,無法操作。

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

以上重新碼完,以下有時間再碼,先去忙了。

鎖機制

為什麼有鎖,事務或者不使用事務,在操作資料實體的時候資料庫會對資料進行加鎖,不加鎖引發的問題不需要解釋吧?熟悉多執行緒的都知道。這就像你用hashMap拿去玩多執行緒。鎖和事務的區別就如同一個是欄位的同步鎖,一個是如何使用該欄位或其副本,二者幾乎沒有關係。

資料庫自帶的鎖分兩類

1.共享鎖

2.排他鎖

增刪改預設使用排他鎖。

查不使用任何鎖,可以在sql最後面新增for update指定使用排他鎖,共享鎖的語句背不下來,就不寫了,網上一大把。

對於同一條資料,只能被加鎖一至多個共享鎖或一個排他鎖。如果資料被共享鎖加持,查詢預設因未使用鎖,可以直接查詢。增刪改因使用排他鎖需要等待共享鎖釋放才能執行,否則等待。排他鎖類似。請反覆研讀此段第一句話和理解各sql預設的鎖。

以上均為業內所謂的悲觀鎖

其他知識:

樂觀鎖,人為在資料裡面加一個欄位作為版本標誌,操作前讀資料,操作的時候直接以where作為條件,如果更新數量不符合實際數量,則迴圈讀取更新。(個人覺得此解決方案不能叫鎖)。

如果資料庫支援行鎖,那麼被加悲觀鎖時,只會鎖幾行,其他資料的增刪改查不受影響。不支援行鎖的資料庫就直接是表鎖了,也就是該表只能這個sql執行完,另一個才能操作。所以實際情況就算用悲觀的排他鎖,也並不會多影響效能,加上有redis做查的快取,其實是能吊打樂觀鎖的,至少我是這麼認為的,畢竟資料庫的連線的代價是很大的。樂觀的迴圈查與更新可能對資料庫造成毀滅性的打擊。

另外事務的隔離級別會影響鎖的時長,這個在下目前只聽說可重複讀及序列的共享鎖會延遲到事務結束。但是實測並不會影響。