【61期】MySQL行锁和表锁的含义及区别(MySQL面试第四弹)
程序员的成长之路
共 2256字,需浏览 5分钟
·
2020-10-16 20:35
阅读本文大概需要 4 分钟。
来自:网络
一、前言
lock in share mode
,例如:select math from zje where math>60 lock in share mode;
for update
,例如:select math from zje where math >60 for update;
二、表锁
MyISAM引擎
表共享读锁
表独占写锁
对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。
对MyISAM表的写操作,会阻塞其它进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。
三、行锁
CREATE TABLE `user` (
`name` VARCHAR(32) DEFAULT NULL,
`count` INT(11) DEFAULT NULL,
`id` INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
-- 这里,我们建一个user表,主键为id
-- A通过主键执行插入操作,但事务未提交
update user set count=10 where id=1;
-- B在此时也执行更新操作
update user set count=10 where id=2;
-- 由于是通过主键选中的,为行级锁,A和B操作的不是同一行,B执行的操作是可以执行的
-- A通过name执行插入操作,但事务未提交
update user set count=10 where name='xxx';
-- B在此时也执行更新操作
update user set count=10 where id=2;
-- 由于是通过非主键或索引选中的,升级为为表级锁, -- B则无法对该表进行更新或插入操作,只有当A提交事务后,B才会成功执行
for update
-- A用户对id=1的记录进行加锁
select * from user where id=1 for update;
-- B用户无法对该记录进行操作
update user set count=10 where id=1;
-- A用户commit以后则B用户可以对该记录进行操作
行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。
两个事务不能锁同一个索引。
insert,delete,update在事务中都会自动默认加上排它锁。
扩展:间隙锁
-- 用户A
update user set count=8 where id>2 and id<6
-- 用户B
update user set count=10 where id=5;
建议:
尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
合理设计索引,尽量缩小锁的范围
尽可能减少索引条件,避免间隙锁
尽量控制事务大小,减少锁定资源量和时间长度
【60期】事务隔离级别中的可重复读能防幻读吗?(MySQL面试第三弹)
【59期】MySQL索引是如何提高查询效率的呢?(MySQL面试第二弹)
微信扫描二维码,关注我的公众号
朕已阅
评论