MySQL鎖與事務隔離機制

2021-10-09 20:37:34 字數 3319 閱讀 4936

事務行鎖和隔離級別的案例分析

鎖是計算機協調多個程序或執行緒併發訪問某一資源的機制。

在資料庫中,除了傳統的計算資源(如cpu、ram、i/o等)的爭用以外,資料也是一種供需要使用者共享的資源。如何保證資料併發訪問的一致性、有效性是所有資料庫必須解決的乙個問題,鎖衝突也是影響資料庫併發訪問效能的乙個重要因素。

表鎖每次操作鎖住整張表。

手動增加表鎖

lock

table 表名稱 read

(write

), 表名稱2

read

(write);

檢視表上加過的鎖

show

open

tables

;刪除表鎖

unlock

tables

;

加讀鎖

lock table mylock read;
當前 session 和其他 seesion 都可以讀該表;

當前 session 中插入或者更新鎖定表都會報錯,其他 session 插入或者更新則會等待。

加寫鎖

lock table mylock write;
當前 session 對該錶的增刪改查都沒有問題,其他 session 對該錶的所有操作都會被阻塞 。

結論

myisam在執行查詢語句(select)前,會自動給涉及的所有表加讀鎖;在執行增刪改查操作前,會自動給涉及的表加寫鎖。

總結:讀鎖會阻塞寫,但不會阻塞讀;而寫鎖則會把讀和寫都阻塞

行鎖每次操作鎖住一行資料。

innodb和 myisam 的最大不同點:

事務及其屬性

事務是由一組 sql 語句組成的邏輯處理單元,事務具有以下四個屬性,通常簡稱為事務的acid屬性

併發事務處理帶來的問題

不可重複讀和幻讀區別:

不可重複讀的重點是修改比如多次讀取一條記錄發現其中某些列的值被修改,幻讀的重點在於新增或者刪除比如多次讀取—條記錄發現記錄增多或減少了。

事務隔離級別有哪些?mysql的預設隔離級別是?

sql標準定義了四個隔離級別:

mysql innodb 儲存引擎的預設⽀持的隔離級別是repeatable-read(可重讀)。oracle預設採用的是read-committed(讀取已提交)

mysql中我們可以通過show variables like 『tx_isolation』; 命令來檢視事務的隔離級別

這⾥需要注意的是:與 sql 標準不同的地⽅在於 innodb 儲存引擎在 repeatable-read(可重讀) 事 務隔離級別下使⽤的是next-key lock 鎖演算法,因此可以避免幻讀的產⽣,這與其他資料庫系統(如 sql server) 是不同的。所以說innodb 儲存引擎的預設⽀持的隔離級別是 repeatable-read(可重 讀) 已經可以完全保證事務的隔離性要求,即達到了 sql標準的 serializable(可串⾏化) 隔離級 別。因為隔離級別越低,事務請求的鎖越少,所以⼤部分資料庫系統的隔離級別都是 readcommitted(讀取提交內容) ,但是你要知道的是innodb 儲存引擎預設使⽤ repeaatable-read(可重 讀) 並不會有任何效能損失。 innodb 儲存引擎在 分布式事務 的情況下⼀般會⽤到 serializable(可串⾏化) 隔離級別

事務控制語句

事務處理方法

mysql 事務處理主要有兩種方法:

用 begin, rollback, commit來實現begin 開始乙個事務rollback 事務回滾commit 事務確認

直接用 set 來改變 mysql 的自動提交模式:set autocommit=0 禁止自動提交set autocommit=1``開啟自動提交

行鎖演示

乙個 session 開啟事務更新不提交,另乙個 seesion 更新同一條記錄會阻塞,更新不同記錄u會阻塞。

案例結論

innodb 儲存引擎由於實現了行級鎖定,雖然在鎖定機制的實現方面所帶來的效能損耗可能比表級鎖定會更高一下,但是在整體併發處理能力方面要遠遠優於 myisam 的表級鎖定的。當系統併發量最高的時候,innodb 的整體效能和 myisam 相比就會有比較明顯的優勢。

但是,innodb 的行級鎖定同樣也有其脆弱的一面,當我們使用不當的時候,可能會讓 innodb 的整體效能表現不僅不能比 myisam 高,甚至可能會更差。

行鎖分析

通過檢查 innodb_row_lock 狀態變數來分析系統上的行鎖的競爭情況:

show status like 'innodb_row_lock%';
對各個狀態量的說明如下:

對於這5個狀態變數,比較重要的主要是:

尤其是當等待次數很高,而且每次等待時長也不小的時候,我們就需要分析系統 中為什麼會有如此多的等待,然後根據分析結果著手制定優化計畫。

優化建議

盡可能讓所有資料檢索都通過索引來完成,避免無索引行鎖公升級為表鎖;

合理設計索引,盡量縮小鎖的範圍;

盡可能減少檢索條件範圍,避免間隙鎖;

盡量控制事務大小,減少鎖定資源量和時間長度,涉及事務加鎖的sql盡量放在事務最後執行;

盡可能低級別事務隔離。

mysql預設級別repeatable-read,有什麼辦法可以解決幻讀嗎?

間隙鎖(gap lock)在某些情況下可以解決幻讀問題,它是 innodb 在可重複讀提交下為解決幻讀問題時引入的鎖機制。要避免幻讀可以用間隙鎖在session_1 下面執行 update user set name = 『hjh』 where id > 10 and id <= 20; ,則其他 session 沒法在這個範圍鎖包含的間隙裡插入或修改任何資料。

如:user 表有3條資料, id > 2 and id <=3 會把第三條記錄鎖住,其他會話對則無法對第三條記錄做操作。

innodb 的行鎖是針對索引加的鎖,不是針對記錄加的鎖。並且該索引不能失效,否則都會從行鎖公升級為表鎖。

鎖定某一行還可以用 local in share mode(共享鎖) 和 for update(排它鎖) ,例如: select * from test_innodb_lock where a = 2 for update; 這樣其他 session 只能讀這行資料,修改則會被阻塞,直到鎖定行的 session 提交。

事務隔離與鎖機制

innodb 儲存引擎既支援行級鎖,也支援表級鎖,預設情況下使用行級鎖。所謂表級鎖,它直接鎖住的是乙個表,開銷小,加鎖快,不會出現死鎖的情況,鎖定粒度大,發生鎖衝突的概率更高,併發度最低。所謂行級鎖,它直接鎖住的是一條記錄,開銷大,加鎖慢,發生鎖衝突的概率較低,併發度很高。所謂頁級鎖,它是鎖住的乙個...

MySQL鎖與事務隔離

1.排他鎖 x鎖 解決多個程式同時修改乙個資料,造成的資料丟失問題。read uncommitted 讀未提交 存在髒讀問題 2.共享鎖 s鎖 解決髒讀問題 甲修改了資料,卻沒有將資料提交或回滾了資料,乙讀到了甲修改後的 錯誤的資料 而不是資料庫中現在真實存在的資料約定 read committed...

mysql事務與鎖機制 mysql事務與鎖機制

在併發下事務會容易出現的一些問題 資料更新丟失 兩個事務同時操作一條資料,乙個事務因為異常導致資料更新丟失 髒讀 乙個失誤開始讀取了某行資料,另外乙個事務已經更新了此資料但沒有能夠及時提交。這是相當危險的,因為很可能所有的操作都被回滾。不可重複讀 乙個事務對同一行資料重複讀取兩次,但是卻得到了不同的...