mysql临界锁_mysql锁
鎖是什么
鎖是管理不同事務之間的并發訪問
理解表鎖和行鎖
在innodb:表鎖是特殊的行鎖,因為是把所有的行都鎖掉的表鎖
鎖定粒度:表鎖 > 行鎖
鎖定效率:表鎖 > 行鎖
沖突概率:表鎖 > 行鎖
并發性能:表鎖 < 行鎖
鎖類型
行鎖:共享鎖(share locks)和排他鎖(exclusive locks)
共享鎖
對同一條讀讀共享,讀寫排斥(修改和刪除),類似于ReentrantReadWriteLock
加鎖方式:
select * from users WHERE id=1 LOCK IN SHARE MODE;
例子:
--共享鎖加鎖
1 BEGIN
select * from users WHERE id=1 LOCK IN SHARE MODE;
2其他事務執行
select * from users where id =1;
update users set age=19 where id =1;
因為讀寫不能共享
排他鎖
讀讀排他,類似于ReentrantLock
加鎖方式:
Insert,delete,update默認加入 for update
Select需要手動添加:如select * from users where id =1 for update;
例子:
1 ?set session autocommit = OFF;
update users set age = 23 where id =1;--可以
select * from users where id =1;--可以,行鎖是針對事務,類似于java的鎖是針對線程
update users set age = 26 where id =1;
2 --其他事務執行
select * from users where id =1 lock in share mode;--不可以,因為排他
select * from users where id =1 for update;--不可以,因為排他
select * from users where id =1;--可以,來自于快照
Innodb行鎖的原理
鎖的是主鍵索引的索引項
通過對索引的索引項(關鍵字)加鎖來實現,若檢索時,需要索引條件則使用行鎖,否則則是表鎖(鎖住索引的所有記錄)
例子:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`age` int(11) NOT NULL,
`phoneNum` varchar(32) NOT NULL,
`lastUpdate` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_eq_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4;
----例子1
set session autocommit = OFF;
update users set lastUpdate=NOW() where phoneNum = '13666666666';--表鎖
rollback;
--其他事務執行
update users set lastUpdate=NOW() where id =2;--不可以,全部的索引項已經鎖住了
update users set lastUpdate=NOW() where id =1;--不可以,全部的索引項已經鎖住了
-----例子2 主鍵索引
set session autocommit = OFF;
update users set lastUpdate=NOW() where id = 1;--行鎖,鎖id=1的索引
rollback;
--其他查詢執行
update users set lastUpdate=NOW() ?where id =2;--可以
update users set lastUpdate=NOW() ?where id =1;--不可以,因為id=1的索引已被鎖住
--------例子3 輔助索引
set session autocommit = OFF;
update users set lastUpdate=NOW() where `name` = 'seven';--行鎖,name是唯一性索引(輔助索引),所對應的是id=1的主鍵索引,索引鎖的是id=1的主鍵索引項
rollback;
--其他查詢執行
update users set lastUpdate=NOW() where `name` = 'seven';--不可以,行鎖
update users set lastUpdate=NOW() where id =1;--不可以,行鎖
update users set lastUpdate=NOW() where `name` = 'qingshan';--可以
update users set lastUpdate=NOW() where id =2;;--可以
表鎖
Lock tables xxx read/write
表鎖:若有行鎖或表鎖,則阻塞
意向共享鎖(intention share locks):在事務操作之前,自動添加的,作用是加共享鎖之前,必須先獲取這把鎖
意向排他鎖(intention exclusive locks):在事務操作之前,自動添加的,作用是加排他鎖之前,必須先獲取這把鎖
意義:針對鎖表功能,鎖表前,先判斷意向鎖是否存在,若存在,則阻塞,若不存在則開始鎖表
例子:
set session autocommit = OFF;
update users set lastUpdate=NOW() where id = 1;--鎖行
rollback;
--其他會話執行
update users set lastUpdate=NOW() where phoneNum = '13777777777';--阻塞
自增鎖(auto-inc locks):
表鎖,類似于通策的主鍵獲取
查看自增模式
show variables like 'innodb_autoinc_lock_mode';
值為1,表示連續提交,事務未提交,丟失
如
begin;
insert into users(name , age ,phoneNum ,lastUpdate ) values ('tom2',30,'1344444444',now());--主鍵:10
ROLLBACK;
begin;
insert into users(name , age ,phoneNum ,lastUpdate ) values ('xxx',30,'13444444444',now());--主鍵:11
ROLLBACK;
-- 其他事務執行
insert into users(name , age ,phoneNum ,lastUpdate ) values ('yyy',30,'13444444444',now());--主鍵:12
上面的例子解釋了為什么自增主鍵主鍵不連續
行鎖的算法
確定鎖的區間大小:左開右閉,左開右開,只有一條記錄
臨界鎖(next-key locks)
1 前提:命中記錄 + 范圍查找[between and,]
2 特點:鎖左開右閉的范圍和下一個區間
查詢結果為7,所在的區間是(4,7],加下一個區間(7,10]
3 間隙的設定:類似于數學的象限,找出臨界點,然后開始找到區間
4 Next-key lock(左開右閉) = gap lock(左開右開) + record lock(一個點,只鎖命中的記錄)
5 為什么鎖下一個區間:解決幻讀
例子:
begin;
select * from t2 where id>5 and id<9 for update;
ROLLBACK
-- 其他事務執行
set session autocommit=off;
select * from t2 where id=4 for update;--不阻塞
select * from t2 where id=7 for update;--阻塞
select * from t2 where id=10 for update;--阻塞
INSERT INTO `t2` (`id`, `name`) VALUES (9, '9');--阻塞
間隙鎖(gap locks)
1 前提:不命中記錄 + (范圍查找或等值查找)
2 特點:左開右開+查詢范圍最近的第一個區間
例子:
begin;
select * from t2 where id >4 and id <6 for update;
--或者
select * from t2 where id =6 for update;
ROLLBACK;
--其他會話執行
INSERT INTO `t2` (`id`, `name`) VALUES (5, '5');
INSERT INTO `t2` (`id`, `name`) VALUES (6, '6');
記錄鎖(record locks)
1 條件:命中記錄 + 等值匹配 + 唯一性索引
2 特點:只鎖住這條記錄
例子:
begin;
select * from t2 where id =4 for update;
rollback;
--其他事務執行
select * from t2 where id =7 for update;--不鎖住
select * from t2 where id =4 for update;--鎖住
總結
以上是生活随笔為你收集整理的mysql临界锁_mysql锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 终极解决苹果开发者中心Edit Phon
- 下一篇: php eclipse aptana,E