一、表鎖
創(chuàng)建表最后面增加 engine = myisam,使用 MyISAM 引擎,MySAM 使用的是表鎖,適合讀,不適合頻繁寫的表。
1. 相關(guān)命令
1. 查詢所有表的鎖使用情況
show open tables;
database: 數(shù)據(jù)庫
table: 表名
in_use: 是否加了鎖
2. 給表加鎖
lock table 表名1 read或write[, 表名2 read或write];
3. 給所有表取消使用的鎖
unlock tables;
4. 鎖分析
show status like 'table%'
table_locks_immediate: 產(chǎn)生表級鎖定的次數(shù),能立即獲取表的次數(shù),和下面相反
table_locks_waited: 被阻塞,不能立即獲取表的次數(shù),此值越高說明爭搶越嚴(yán)重
2.讀、寫鎖
1. read
| 當(dāng)前線程 | 其他線程 | |
|---|---|---|
| 讀加鎖的表 | ok | ok |
| 讀未加鎖的表 | error | ok |
| 寫加鎖的表 | error | 阻塞 |
| 寫未加鎖的表 | error | ok |
2. write
| 當(dāng)前線程 | 其他線程 | |
|---|---|---|
| 讀加鎖的表 | ok | 阻塞 |
| 讀未加鎖的表 | error | ok |
| 寫加鎖的表 | ok | 阻塞 |
| 寫未加鎖的表 | error | ok |
二、行鎖
用 InnoDB 引擎,行鎖不用像表鎖中顯式聲明,開啟事務(wù)即可
| 當(dāng)前事務(wù) | 其他事務(wù) | |
|---|---|---|
| 不同行讀 | ok | ok |
| 同行讀 | ok | ok |
| 不同行寫 | ok | ok |
| 同行寫 | 阻塞 | 阻塞 |
對于不同行的讀寫,兩個(gè)事務(wù)互不干擾,可以各自進(jìn)行;
若事務(wù)讀同一行數(shù)據(jù),可以讀,查詢結(jié)果遵循隔離級別;
若事務(wù)寫同一行數(shù)據(jù),后寫者會(huì)阻塞。
所以,InnoDB 引擎下,開啟事務(wù)就能解決并發(fā)寫的問題。
*注意:索引失效將導(dǎo)致行鎖變表鎖
間隙鎖(next-key鎖)
當(dāng)一個(gè)事務(wù)使用用范圍檢索時(shí),這個(gè)范圍內(nèi)的所有索引建值,即使并不存在這個(gè)鍵值;對于被鎖定卻并不存在的記錄,就稱為間隙,此時(shí)是插入相關(guān)的數(shù)據(jù)會(huì)受到阻塞,而這種鎖機(jī)制就是“間隙鎖”。
比如:一個(gè)事務(wù)中使用了 where id > 10 這個(gè)條件,那么,即使沒有 id = 11 的數(shù)據(jù),里一個(gè)事務(wù)也無法插入 id 為 11 的數(shù)據(jù)。
如何鎖定指定行?
查出改行數(shù)據(jù)并在結(jié)尾增加 for update,例如:
select * from t1 where id=1 for update;
這樣即可鎖定 id=1 的這行數(shù)據(jù)。
相關(guān)命令
#鎖信息
show status like 'innodb_row_lock%'