基本命令
查看那張表被鎖住烈掠,其中In_use字段大于0則表被鎖括蝠。
show open tables;
給某張表上鎖
lock table 【表名】【read/write】;
釋放所有的鎖
unlock tables;
查看引擎
show engines;
查看自動(dòng)提交狀態(tài)
show variables like 'autocommit';
表鎖
以下是在MyISAM引擎下斑胜,MyISAM偏讀控淡。
準(zhǔn)備
- t_logs 表一張。
- session1 給t_logs上讀鎖或?qū)戞i止潘。
- session2 不做任何與鎖有關(guān)操作掺炭。
讀鎖
讀鎖也叫共享鎖。
Session1 | Session2 |
---|---|
可以查詢 t_logs 表 | 可以查詢 t_logs 表 |
不可以更新 t_logs 表 | 不可以更新 t_logs 表 會阻塞覆山,必須等待鎖釋放 |
不可以查詢別的表 | 可以查詢別的表 |
不可以更新別的表 | 可以更新別的表 |
總結(jié):當(dāng)前會話為某張表加了讀鎖竹伸,當(dāng)前會話僅僅能讀取加鎖的表,任何其它操作都不能做簇宽。而其他會話對此表只有讀的權(quán)限勋篓,但除此之外的表,則正常操作魏割。
寫鎖
寫鎖也叫排它鎖譬嚣。
Session1 | Session2 |
---|---|
可以查詢 t_logs 表 | 不可以查詢 t_logs 表 會阻塞 |
可以更新 t_logs 表 | 不可以更新 t_logs 表 會阻塞,必須等待鎖釋放 |
不可以查詢別的表 | 可以查詢別的表 |
不可以更新別的表 | 可以更新別的表 |
總結(jié):當(dāng)前會話為某張表加了寫鎖钞它,那么當(dāng)前會話就獨(dú)享了這張表拜银,擁有這張表的讀寫權(quán)限殊鞭,且不能夠?qū)Τ吮碇獾娜魏伪碜鋈魏尾僮鳌F渌鼤捯膊豢梢詫Υ吮磉M(jìn)行任何操作尼桶。
行鎖
行鎖演示是在InnoDB引擎下操灿,該引擎支持事務(wù),并且為了并發(fā)性能引進(jìn)了行級鎖泵督。上行鎖的方式有兩種:
- select * from t_logs where id = 1 for update 其中增刪改操作自動(dòng)上行鎖趾盐,相當(dāng)于上了寫鎖(排它鎖)。
- select * from t_logs where id = 1 lock in share mode 相當(dāng)于上了讀鎖(共享鎖)小腊。
準(zhǔn)備說明
為了演示效果救鲤,先關(guān)閉自動(dòng)提交功能或者也可以手動(dòng)開啟事務(wù)。
set autocommit = 0 或者 begin
步驟
- 開啟session1
- set autocommit = 0
- update t_logs set name = 'lisi' where id = '1';
- 開啟session2
- set autocommit = 0
- 讀取秩冈、修改 id = 1 的這條記錄
結(jié)論
在Session1執(zhí)行 commit 命令之前本缠,假設(shè)修改 id = 1 的這一行,得出如下結(jié)論:
Session1 | Session2 |
---|---|
能夠修改id為1的這一行 | 除了id為1的這一行都可以修改 |
也能夠修改別的記錄 但修改哪條記錄入问,那條記錄就被鎖住 |
除了被鎖住的記錄不能修改以外(可以讀)丹锹,其它都可以修改 |
總結(jié):行級鎖顧名思義就是鎖定數(shù)據(jù)庫中的一行或者符合where
條件的某些行,對于數(shù)據(jù)庫來說開銷比鎖一張表大队他,但是發(fā)生鎖沖突的概率比表鎖小很多卷仑,并發(fā)性能高很多,當(dāng)前會話鎖住這一行后麸折,其它會話要想修改這一行锡凝,必須等待上一個(gè)會話進(jìn)行事務(wù)的提交,否則就會阻塞在這里垢啼。但對于其它未被鎖住的行窜锯,是不受任何影響的。
間隙鎖
什么時(shí)候會發(fā)生間隙鎖芭析?看下面例子:
mysql> select * from t_permission;
+----+----------------+-------------+
| id | url | description |
+----+----------------+-------------+
| 1 | /user/create | create |
| 3 | /user/update | update |
| 4 | /user/retrieve | retrieve |
| 5 | /user/delete | delete |
+----+----------------+-------------+
t_permission 表 id 為主鍵锚扎,但缺少了 id = 2,當(dāng)我們使用范圍更新數(shù)據(jù)的時(shí)候馁启,如下語句:
update t_permission set description = '666' where id > 0 and id < 6;
將 id = 2 包括了進(jìn)去焰望,那么mysql默認(rèn)的會將這個(gè)范圍之內(nèi)所有的連續(xù)id都上鎖买决,與此同時(shí)最欠,在另一個(gè)會話中進(jìn)行插入 id = 2 的數(shù)據(jù)操作:
insert into t_permission values(1,'222','222');
那么這個(gè)插入操作會阻塞荚斯,這就是間隙鎖。如果線上環(huán)境發(fā)生了這樣的鎖等待霉颠,很不好發(fā)覺对碌,可以用show profile命令來排查。