MYSQL事務和鎖
2020年11月12日17:20:52 MYSQL事務 王凱玉
目錄
事務的定義
事務是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成
儲存引擎
預設的innodb可以滿足大部分併發讀寫 、NDB適用於叢集 這兩個都支援事務
事務的四大特性
最終都是為了保證一致性
- 原子性 - 事務不可分割,是一個邏輯單位
- 一致性 - 資料庫的自身完整性的約束,不能被破壞,在使用者的程式碼中控制
- 隔離性 - 有很多事務去同時操作一張表,這種併發操作應該是互不干擾的
- 永續性 - 對資料庫進行增刪改的操作時,只要事務提交成功,結果應該是永久性的,不管資料庫是崩潰了還是重啟了,資料都不會恢復到之前的狀態
資料庫什麼時候會出現事務?
執行一個增刪改的語句的時候 自動開啟事務
-
start transaction 手動開啟事務
-
begin 手動開啟事務
-
commit 提交
回滾和提交都可以結束事務,在圖形化介面裡 斷開連線 會自動回滾
事務可以去鎖定一行資料,在結束事務的時候會釋放鎖
事務併發會帶來什麼問題?
-
髒讀(READ UNCOMMITTED)
一個事務讀取到了其他事務還沒有提交的資料,造成前後兩次讀取的結果不一致
(沒有提交的資料在記憶體的緩衝池中 不會寫入到磁碟中)
-
不可重複讀(READ COMMITTED)
一個事務讀取到了其他事務已提交的資料,造成前後兩次讀取結果不一致
-
幻讀(REPEATABLE READ)
新增資料 造成事務的兩次讀取結果不一致
總結: 事務併發的三大問題,都是資料庫讀一致性的問題
必須由資料庫提供一定的事務隔離機制來解決。
事務的四種隔離級別(SQL92標準)
-
未提交讀(Read Uncommitted):一個事務可以讀取到其他事務未提交的資料,會出現髒讀 這最低的事務隔離級別
-
已提交讀(Read Committed):解決髒讀,但是不能解決不可重複讀的問題
-
可重複讀(Repetable Read):解決髒讀和不可重複讀,不能解決幻讀
-
序列化(Serializable):解決事務併發的所有問題,事務一個個排隊執行 沒有了併發
副作用:執行速度慢(操作一張資料表的時候 其他事務不能做操作,併發效率降低,生產環境中不會使用)
MYSQL比較貼近這個標準,事務隔離級別越高,支援的併發度就越低。
”可重複讀“:在innodb中 已經解決了所有問題
Q:想要保證一個事務中前後兩次讀取資料結果一致?
A:- 在讀取資料之前,加鎖,組織其他事務對資料進行修改
- 生成一個數據請求時間點的一致性資料快照,用這個快照提供一定級別的一致性讀取
MYSQL中的鎖
從鎖的粒度劃分:行鎖、表鎖
從鎖的用法劃分:樂觀鎖、悲觀鎖
從鎖的型別劃分:
-
排他鎖:又叫寫鎖,不能和其他鎖並存,一個事務獲取了一個數據行的排他鎖,其他事物就不能再獲取這個鎖,只有獲取了排他鎖的事務才能操作資料
# 加鎖 - 自動:delete/update/insert # 預設上鎖 - 手動:select * from student where id = 1 FOR UPDATE;
-
共享鎖:又叫讀鎖,多個事務都可以共享這把鎖,都能訪問到資料,但是隻讀不能修改。
# 加鎖 slect * from student where id = 1 LOCK IN SHARE MODE; # 釋放 (釋放共享鎖就是事務的結束) commit/rollback ;
鎖的作用:競爭資源