mysql事務總結

2021-08-25 15:33:20 字數 2751 閱讀 9863

1 簡 介

mysql 框架本身不直接支援事務,而由引擎實現。常用引擎中,僅 innodb 支援事務, myisam 和 heap 引擎皆不支援事務,下文對事務的介紹皆以 innodb 為準。

mysql框架提供多條語句用於操作事務,常用語句如下:

start transaction

commit

rollback

set autocommit=

autocommit 屬性用於控制是否自動提交,預設情況下是「1」,表示每個更新語句都

是單獨的事務。可通過「set autocommit」語句將該值設定為 0,表示不自動提交。 「start transaction」語句用於優雅的啟動乙個事務,它忽略 autocommit 屬性,直到事務結束。

2 隱 式 提 交 和 回 滾

2 . 1 簡 介

有些語句會導致乙個事務被隱式提交,包括各種 ddl 語句、一些事務操作語句等,具 體參見 mysql 手冊

當事務中發生某些異常情況時,innodb 將隱式回滾事務:

回滾 sql 語句時,innodb 不會釋放為執行該 sql 獲得的鎖。

2 . 2 t i p s

3 事 務 隔 離

3 . 1 簡 介

事務之間需要有一定的隔離來避免相互影響,為了區分不同的影響程度,sql 標準規定了四種隔離級別:

乙個事務能夠讀到另乙個事務尚未提交的中間結果,這會導致「髒讀」。

僅當事務已提交,其結果才可見。該級別存在「nonrepeatable read」(不可重複讀)

的問題——事務過程中,相同 select 語句的結果可能被外界改變。

解決「nonrepeatable read」:乙個事務所讀的行內容在該事務後續生命期中保持一 致。存在「phantom reads」(幻讀)問題:事務過程中,相同的 where 條件可能讀到更 多的行。

將可能衝突的事務序列化。

innodb 支援所有四種隔離級別,預設且推薦的級別是「repeatable read」,並且

innodb 解決了該級別的「phantom reads」問題。

innodb 採用 mvcc 機制來實現事務的隔離,mvcc 的基本思想是為不同的事務儲存其當 時資料的快照(稱為「版本」),它既能保證事務內資料的一致性,又避免了鎖的大量使用, 從而提公升了效能和併發性。

innodb 實現了一種非常高效的 mvcc,它並不會為事務訪問的資料真正建立快照,而 是通過類似於時間戳的「版本號」機制來確保拿到未被其他事務修改的資料。所謂「版本號」其實是 innodb 維護的乙個計數器,每啟動乙個事務,計數器隨著遞增,並將該號作為事 務的版本號。

在預設的「repeatable read」隔離級別下,當執行各類 sql 時 innodb 是這麼做的:

innodb 將系統當前的版本號設為新增行的版本號。

innodb 對比當前事務的版本號和找到行的版本號/刪除號,當滿足如下條件時,行被

select 出來:

行版本號不大於事務版本號。這確保了該行在事務開始時已存在,或者由當前事務建立、更新;

行刪除號不存在,或者刪除號大於事務版本號。這確保事務開始前行未被刪除;

在該機制下,乙個事務總是能看到自己開始時的資料狀態,不會受到其他事務的影響。

對於被標記為刪除的行,innodb 有專門的「淨化執行緒」(purge thread)負責定期進 行物理刪除,當行滿足如下條件時,認為可以將其物理刪除:當前不存在版本號小於該行刪 除號的事務。這樣可確保不會有事務再引用到該行。

3 . 2 t i p s

4 事 務 和 鎖

4 . 1 簡 介

innodb 使用鎖機制來實現事務執行結果的一致性,在事務中執行寫操作時,innodb

會隱式地鎖定相關行,避免同時寫入。

同時,innodb 也允許應用自行加鎖——當應用需要先讀出一些行,再根據這些行進 行寫操作時,需要手動加鎖來保證資料一致。innodb 提供了兩種顯式鎖:

【顯式共享鎖】

select ... lock in share mode

此模式下,當前事務將獲得對所有行的 s 鎖,其他事務試圖更新這些行時會阻塞。 顯式共享鎖可能導致死鎖——當需要在加鎖後寫這些行時,事務必須取得 x 鎖,此時

如果兩個併發事務同時執行,則很可能另乙個事務已經拿到了 s 鎖,並且也試圖拿到 x 鎖—

—於是發生死鎖。

【顯式獨佔鎖】

select ... lock for update

顯式獨佔鎖用於解決經典的「test and set」問題,同時也能避免顯式共享鎖可能導 致的死鎖問題。執行顯式獨佔鎖的事務將獲得對所有行的 x 鎖,其他事務試圖獲得 x 或 s 鎖 時將會阻塞。

以倉庫系統為例:

假設倉庫表中有乙個 wcount 字段,指出當前倉庫放了多少貨物,當貨物超過 100 時, 倉庫滿了,不能再放。此時,向乙個倉庫放入貨物需要判斷倉庫是否滿,並且需要增加倉庫 貨物計數。如果有多個事務同時向乙個已存了 99 件貨物的倉庫中放貨物時,則很可能出現 倉庫溢位的情況。

這可以使用顯式獨佔鎖來解決:

select id from warehouse where wcount < 100 and *** lock for update

; if(failed)exit;

update ware set whid = *** where wid = ***;

update warehouse set wcount = wcount + 1 where id=***;

4 . 2 t i p s

使用事務時需要加以注意;

5 事 務 t i p s

mysql事務總結 mysql事務特點總結

1.mysql事務有4個隔離級別,以及會出現的問題如下圖 2.髒讀 開啟事務a,b。事務a在還沒有提交的情況下,假如第一次查詢id 1的使用者的age 24。事務b執行了update 表 set age 100 where id 1 b事務並沒有提交,緊接著再次查詢id 1的使用者的age時,age...

mysql鎖與事務總結

未提交讀,乙個事務查詢到另乙個事務未提交資料 髒讀 提交讀,乙個事務中兩次查詢可能查出不同資料 不可重複讀 可重複讀,乙個事務中每次查詢到的資料集相同 幻讀 串性化mysql資料引擎innodb,支援事務,預設使用行鎖,行鎖開銷大但粒度小,併發處理能力高。當執行insert update delet...

mysql 事務 數量 Mysql 事務

什麼是事務 不可分割的操作,比如乙個事務要修改 a 表和刪除 b 表的資料兩個操作,這兩個操作都成功,這個事務才 commit,不然 rollback 每條 sql 語句都是乙個事務 只對 dml 生效 caid 一致性 consistency 讓資料保持一定程度的合理性,比如使用者加入購物車,購物...