目錄
- 事務
- 并發三大問題
- 排他鎖和共享鎖
- 事務隔離
- 全域鎖
- 表鎖
- 行鎖
- 記錄鎖
- 間隙鎖
- 臨鍵鎖
- 引擎間的鎖機制
事務
-
原子性
事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節,
-
一致性:
執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態,因此當資料庫只包含成功事務提交的結果時,就說資料庫處于一致性狀態,
-
隔離性
一個事務的執行不能被其他事務干擾,即一個事物內部的操作及使用的資料對并發的其他事務是隔離的,并發執行的各個事物之間不能互相干擾
-
持久性
一個事務的執行不能被其他事務干擾,即一個事物內部的操作及使用的資料對并發的其他事務是隔離的,并發執行的各個事物之間不能互相干擾
begin; #開始事務
...
rollback; #回滾事務
savepoint 回滾點; #添加回滾點
rollback to 回滾點; #回滾到指定回滾點
...
commit; #提交事務
并發三大問題
-
丟失修改:兩個都改
事務T1和事務T2同時讀入同一資料進行修改,T1或者T2修改資料丟失的問題
-
不可重復讀:一讀一改
事務T1讀取資料后,事務T2修改資料,使得T1兩次讀取的值不一致的問題
-
讀臟資料的問題:一讀一改 + 事務撤銷
事務T2修改資料,事務T1讀資料,T2事務撤銷,T1讀取資料不正確
排他鎖和共享鎖
-
排他鎖:寫鎖
當前事務給資料添加寫鎖后,其他事務既不能讀,也不能寫,也不能添加鎖,
-
共享鎖:讀鎖
當前事務給資料添加讀鎖后,其他事務僅可以讀,當前資料所有讀鎖釋放后,才可以添加寫鎖,
-
一級封鎖協議
事務T在修改資料R之前必須獲得排他鎖(解決丟失修改問題)
-
二級封鎖協議
一級封鎖協議+事務T在讀資料R之前必須先對資料添加共享鎖,讀完立即釋放(解決丟失修改和讀臟資料的問題)
因為事務結束前釋放了共享鎖,因此其他事務可以進行修改資料,因此無法解決不可重復讀問題,
-
三級封鎖協議
一級封鎖協議+事務T在讀資料R之前必須先對資料添加共享鎖,且事務結束后才釋放共享鎖,
事務隔離
-
讀-未提交(read uncommitted):未上鎖
事務T1可以查看事務T2未提交的資料,(讀臟資料的問題)
-
讀-已提交(read committed): 上了寫鎖,提交后解鎖
事務T1只能讀取到T2已經提交后的資料,(不可重復讀)
-
可重復讀(repeatable read): 三級封鎖協議
事務T1讀取一張表時,事務T2不能修改那張表的資料,(幻讀: 資料不真實)
-
序列化/串行化(serializable)
并發都沒了,事務T1和事務T2不能對同一張表操作,
# 查看事務隔離級別
select @@transaction_isolation;
# 設定事務隔離級別
set global transaction ioslation level 隔離級別
全域鎖
全域鎖就是對整個資料庫實體加鎖,即資料庫中的所有表都將被加上鎖,加鎖后整個實體就處于只讀狀態,后續的DML的寫陳述句,DDL陳述句,已經更新操作的事務提交陳述句都將被阻塞,
# 開啟全域鎖,全域鎖只有讀
flush tables with read lock;
# 解除全域鎖
unlock tables;
表鎖
表鎖作用于某一張表,是MyISAM和InnoDB存盤引擎支持的方式,是
MyISAM的默認鎖機制,
# 添加寫鎖/讀鎖
lock table 表名稱 read/write;
# 解鎖
unlock tables;
為表添加寫鎖后,不能讀取表中任何資料,
為表添加讀鎖后,不能修改表中任何資料,
行鎖
僅
InnoDB引擎支持行鎖
-- 添加讀鎖(共享鎖), 只能在事務中使用
select * from ... lock in share mode;
-- 查詢時添加寫鎖(排他鎖)
select * from ... for update;
-- 更新時自動添加寫鎖
update 表名 set xxx = xxx where xxx
行鎖的細分,了解一下就好,
記錄鎖
(Record Locks)記錄鎖, 僅僅鎖住索引記錄的一行,在單條索引記錄上加鎖,Record lock鎖住的永遠是索引,而非記錄本身,即使該表上沒有任何索引,那么InnoDB會在后臺創建一個隱藏的聚集主鍵索引,那么鎖住的就是這個隱藏的聚集主鍵索引,所以說當一條sql沒有走任何索引時,那么將會在每一條聚合索引后面加寫鎖,類似于表鎖,但原理上和表鎖是完全不同的,
間隙鎖
(Gap Locks)僅僅鎖住一個索引區間(開區間,不包括雙端端點),在索引記錄之間的間隙中加鎖,或者是在某一條索引記錄之前或者之后加鎖,并不包括該索引記錄本身,比如在 1、2中,間隙鎖的可能值有 (-∞, 1),(1, 2),(2, +∞),間隙鎖可用于防止幻讀,保證索引間的不會被插入資料,
臨鍵鎖
(Next-Key Locks)Record lock + Gap lock,左開右閉區間,默認情況下,
InnoDB正是使用Next-key Locks來鎖定記錄(如select … for update陳述句)它可以根據場景進行靈活變換:
| 場景 | 轉換 |
|---|---|
| 使用唯一索引進行精確匹配,但表中不存在記錄 | 自動轉換為 Gap Locks |
| 使用唯一索引進行精確匹配,且表中存在記錄 | 自動轉換為 Record Locks |
| 使用非唯一索引進行精確匹配 | 不轉換 |
| 使用唯一索引進行范圍匹配 | 不轉換,但是只鎖上界,不鎖下界 |
引擎間的鎖機制
使用InnoDB的情況下,在執行更新、洗掉、插入操作時,資料庫也會自動為所涉及的行添加寫鎖(排他鎖),直到事務提交時,才會釋放鎖,執行普通的查詢操作時,不會添加任何鎖,而當不使用where陳述句時,行鎖會升級為讀鎖,
使用MyISAM的情況下,在執行更新、洗掉、插入操作時,資料庫會對涉及的表添加寫鎖,在執行查詢操作時,資料庫會對涉及的表添加讀鎖,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/499386.html
標籤:MySQL
上一篇:1. SQL
