MySQL —— 锁

表锁

添加表锁

lock table t10 write;

查看表锁

show OPEN TABLES where In_use > 0;

关闭表锁


## 方法一:找到锁进程,kill id ;
show processlist;


## 方法二
unlock table;

意向锁

验证意向锁

对记录r加上一个行锁,然后对整张表加锁。

对行记录进行加锁

select * from t10 where name = 'zhang' for update;

开启另一个session,对表加上写锁。当前事务进入阻塞状态,一直到上一个事务提交,释放掉排它锁。

lock table t10 write;

解决数据丢失更新问题

数据丢失更新问题,指的是业务上,T1对r进行读取操作,得到数据score = 1,T2也对r进行读取操作,得到数据score = 1,T1对r进行更新score +1,T2也对r进行更新 score + 1,最后的记过是socre = 2;发生丢失更新的问题。

解决方法是 使用 select....for update

begin;

select classid into @classid from student where stuid = 1 for update;

update student set classid=@classid + 1 where stuid = 1;

commit;

间隙锁

创建表插入数据

CREATE TABLE `innodb_lock` (
  `a` int(10) NOT NULL,
  `b` varchar(255) NOT NULL DEFAULT '',
  KEY `index_a` (`a`),
  KEY `index_b` (`b`)
) ENGINE=InnoDB;


INSERT INTO `innodb_lock` VALUES ('1', 'b2');
INSERT INTO `innodb_lock` VALUES ('3', '3');
INSERT INTO `innodb_lock` VALUES ('4', '4000');
INSERT INTO `innodb_lock` VALUES ('5', '5000');
INSERT INTO `innodb_lock` VALUES ('6', '6000');
INSERT INTO `innodb_lock` VALUES ('7', '7000');
INSERT INTO `innodb_lock` VALUES ('8', '8000');
INSERT INTO `innodb_lock` VALUES ('9', '9000');

开启一个session,开启事务

set autocommit=0;

update innodb_lock set b = 'haha' where a>1 and a<6;

开启另一个session,开启事务,执行插入语句,会发现存在间隙锁。插入语句陷入阻塞。

set autocommit=0;
insert into innodb_lock values(2,'2000');

Next-key锁

它是间隙锁和普通行锁的一种组合。

单纯只是间隙锁的话,如果记录中只有id=50,则一个事务执行select * from t where id > 49 for update,另一个事务执行修改id = 50的记录是可以操作成功,不阻塞的。因为间隙锁,锁的是不包含记录本身,只锁区间范围内不存在的记录。

而Next-key锁,则是既锁不存在的记录,又锁存在的记录。

select..for update

什么情况下会锁表

主键不明确,查询非主键时会锁表。这条语句不管查没查到结果,都会锁表。

SELECT * FROM student WHERE stuaddress='beijing' FOR UPDATE;

主键不明确,锁表。

select * from student where stuid <> 1 for update;
posted @ 2020-04-16 03:21  清泉白石  阅读(180)  评论(0编辑  收藏  举报