MySQL的锁分类以及使用场景

myisam存储引擎默认是表级锁

innodb存储引擎默认是行级锁

DBD存储引擎默认是页面锁

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

行级锁:开锁大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

从上述特点可见,很难笼统的说哪种锁更好,只能就具体应用的特点来说哪种锁更合适!仅从锁的角度来说:表级锁

更于以查询为主,只有少量按索引条件更新数据的应用,如WEB应用;而行级锁则更适合于有大理按索引发更新少量

不同数据,同时又有并发查询的应用,如一些在线事务处理系统。


for update的锁表

InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

例子: 假设表foods ,存在有id跟name、status三个字段,id是主键,status有索引。

例1: (明确指定主键,并且有此记录,行级锁)

SELECT * FROM foods WHERE id=1 FOR UPDATE;

SELECT * FROM foods WHERE id=1 and name=’咖啡色的羊驼’ FOR UPDATE;

例2: (明确指定主键/索引,若查无此记录,无锁)

SELECT * FROM foods WHERE id=-1 FOR UPDATE;

例3: (无主键/索引,表级锁)

SELECT * FROM foods WHERE name=’咖啡色的羊驼’ FOR UPDATE;

例4: (主键/索引不明确,表级锁)

SELECT * FROM foods WHERE id<>’3’ FOR UPDATE;

SELECT * FROM foods WHERE id LIKE ‘3’ FOR UPDATE;

for update的注意点

1.for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。

2.要测试for update的锁表情况,可以利用MySQL的Command Mode,开启二个视窗来做测试。

for update的疑问点

当开启一个事务进行for update的时候,另一个事务也有for update的时候会一直等着,直到第一个事务结束吗?

答:会的。除非第一个事务commit或者rollback或者断开连接,第二个事务会立马拿到锁进行后面操作。

如果没查到记录会锁表吗?

答:会的。表级锁时,不管是否查询到记录,都会锁定表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容