MySQL 事務和鎖

2021-08-10 05:40:52 字數 2888 閱讀 8367

和其他資料庫相比,mysql的鎖機制比較假單,不同的引擎支援不同的鎖機制。myisam和memory使用表級鎖,bdb使用頁面鎖和表級鎖;innodb預設支援行級鎖,也支援表級鎖。

myisam表鎖有兩中,乙個是都鎖,乙個是寫鎖,相容性如下:

模式讀鎖

寫鎖讀鎖

相容不相容

寫鎖不相容

不相容

可見myisam對錶的讀取不會造成其他使用者對錶的讀取,但會阻塞其他用的寫。因此,除了讀-讀操作,其他對資料的操作都是序列的。

myisam在執行select前,會自動的給涉及到的所有表加讀鎖,使用跟新操作前都會自動的加寫鎖,這些過程不需要使用者干預。

併發插入:在一定程度上,myisam也支援查詢和插入操作的併發進行。myisam中有乙個系統變數concurrent_insert,專門控制併發插入,可以取值為0、1、2。

對於同時存在讀寫操作競爭鎖的時候,預設情況下myisam中寫程序會先獲得鎖,也就是說myisam認為寫請求比讀請求更加重要。這也就解釋了myisam不適合有大量跟新操作的原因,因為大量的更新操作會使得讀執行緒很難獲得鎖,從而造成永遠的阻塞。我們通過一些設定來改變這種情況。

指定啟動引數low-priority-updates,使得讀請求有優先的權利。

執行set low_priority_updates=1.

指定insert、update、delete語句的low_priority屬性。

innodb是支援事務的,這是和myisam最大的不同。

事務以及acid屬性:

事務併發處理帶來的問題

事務隔離級別

1.read uncommitted未提交讀:從名字可以知道,在該級別下,乙個事務對一行資料修改的過程中,允許另乙個事務對該行資料進行修改。

2.read committed已提交讀:在該級別下,乙個事務對一行資料修改的過程中,不允許另乙個事務對該行未提交資料進行修改,但允許另乙個事務對該行資料讀。 雖然解決了髒讀,但是會出現不可重複讀和幻讀。

3.repeatable read可重複讀:在該級別下,讀事務禁止寫事務,但允許讀事務,因此解決了不可重複讀,且寫事務禁止其他一切事務。

4.serializable 序列化:最高的隔離級別,該級別下,讀事務禁止寫事務,但允許讀事務,且寫事務禁止其他一切事務。

資料庫實現事務隔離機制的方法主要有兩種

innodb中預設的是行級鎖,和myisam一樣有兩種鎖:

鎖模式xs

x衝突衝突s

衝突相容

對於update、insert、delete語句,innodb會自動的加上x鎖;一般的select語句不會加鎖,除非顯示的給記錄集加上鎖。如果取得資料的共享鎖以後,還要進行更新,就會造成死鎖(後面會講到);因此如果要對資料要進行更新就直接獲得排它鎖即可。

innodb行鎖是通過給索引上的索引項加鎖來實現的,從而間接對一行資料集上鎖,如果沒有索引,那麼就會通過隱藏的聚集索引來對記錄上鎖。行鎖有三種:

這種加鎖機制表名,如果不通過索引條件查詢資料,那麼innodb將會對錶中所有資料記錄加鎖,這就和表鎖的實際效果一樣了。因此需要注意如下情況:

不通過索引查詢資料,innodb會鎖定整個表記錄。

如果不同事務使用相同的索引鍵則會出現鎖衝突。

表有多個索引時候,不同事務使用不同的索引鎖定不同的行,無論使用哪種索引,都會鎖定資料。

事務1查詢 select * from table where id = 1 for update;

結果id :1 name :1

id:1 name:4

事務2查詢 select * from table where name= 4 for update ;

會造成阻塞,知道事務1釋放鎖。對於鍵值在條件範圍以內但並不存在記錄的叫做「間隙」,innodb會對這個間隙加鎖,這就是所謂的next-key鎖。

select * from

table

where id>100

forupdate;

對於上述語句,innodb不僅會對id位為101記錄上鎖,而且還會對大於101的記錄上鎖,雖然這些記錄並不存在。innodb使用next-key 鎖的好處就是防止了幻讀的出現,以滿足相關隔離級別的要求。雖然innodb預設的隔離級別是rr(可重複讀),但是防止了幻讀的出現,實際上達到了serializable級別。

很顯然,這也會帶來乙個問題:在使用範圍查詢時,innodb這種加鎖機制會造成嚴重的鎖等待,所以在實際開發中需要優化業務邏輯,避免出現範圍條件。

當兩個事務都需要獲得對方的排他鎖時,會出現迴圈等待,也就是「死鎖」。對於innodb,死鎖都能自動檢測到,並使得乙個事務回滾並釋放鎖。

避免死鎖的辦法:

1.設定合適的鎖等待時間,一旦超過這個時間閾,就會自動回滾並釋放鎖。

2.盡量約定以相同的順序來訪問表,這就會大大降低產生死鎖的機會。

3.在事務中,申請足夠級別的排他鎖,如:需要更新資料就直接申請排它鎖。

4.死鎖很難避免,因此需要在程式設計中捕獲並處理死鎖異常是乙個好的習慣。

myisam鎖的特點?以及鎖的排程機制?innodb的行鎖是如何實現的?innodb為什麼在rr級別下解決了幻讀的出現?innodb如何減少死鎖的發生?

mysql 事務和鎖

事務是dbms得執行單位 開啟事務 set autocommit 0 取消自動提交 或begin 手動開啟乙個事務 提交乙個事務 commit 回滾乙個事務 rollback 在mysql的innodb 引擎中,預設每個操作 insert,update,select for update lock ...

Mysql 事務和鎖

是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過將一組相關操作組合為乙個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢復並使應用程式更加可靠。乙個邏輯工作單元要成為事務,必須滿足所謂...

mysql事務和鎖

參考文章 1 原子性 atomicity 事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節。事務執行過程 錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是乙個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。2 一致性 consistency 事...