ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL锁

2021-10-31 01:00:53  阅读:224  来源: 互联网

标签:加锁 行锁 查询 读锁 MySQL 操作 表锁


锁概述


锁是计算机协调多个进程或者线程并发访问同一资源的机制。

在数据库中,数据提供给多个用户使用。如何保证数据并发访问时的有效性和一致性是所有数据库都必须解决的问题。锁对数据库来说极其重要,如果没有锁,我们存储在数据库的数据将会不准确,对数据库来说,它就不是一个可用的数据库了。

锁分类


对数据操作的粒度来区分:
表锁:操作记录时,会导致整张表被锁定,其他用户不能操作;
行锁:操作的行记录,会被锁定,其他用户不能操作该行记录;

对数据操作的类型区分:
读锁:也叫共享锁,针对同一份数据,多个读操作不行会相互影响;
写锁:也叫排它锁,在修改同一份数据时,禁止其他用户操作该行纪录;

MySQL存储引擎锁支持


  • MyISAM:表锁
  • InnoDB:表锁、行锁
  • MEMORY:表锁

表锁开销小、加锁快、不会出现死锁,但是锁的颗粒度比较大,容易发生锁冲突,并发度较低;
行锁开销大、加锁慢、容易死锁,但是加锁颗粒度较小,不容易产生锁冲突,并发度较高;

锁有各自的优势,表锁比较适合以查询为主的系统,而行锁则适合以并发操作数据为主的系统。

MyISAM表锁


MyISAM存储引擎会在执行查询语句前,自动给涉及的表加上读锁,在涉及更新操作时会自动加上写锁。如果我们想显示的进行操作,可使用下列语法操作:

-- 给表加读锁
LOCK TABLE 表名 READ;

-- 给表加写锁
LOCK TABLE 表名 WRITE;

-- 解锁
UNLOCK TABLE;

在给表加读锁后,获取读锁的客户端获得读锁,这时当前客户端只能操作当前表,如果在未进行解锁操作时,不可再操作其他表。其他线程可继续读取该表数据,但是不可进行写操作。

在给表加了写锁后,加锁的客户端对该表可进行增删改查的操作,但是其他客户端的操作则会被阻塞,等待加锁的客户端解锁后,数据才能正常操作。

InnoDB行锁


InnoDB不仅支持表锁,还支持行锁;行锁主要针对操作的行进行加锁,在进行更新、删除、插入操作,InnoDB引擎都会自动添加写锁。

对于查询语句,InnoDB引擎不会加任何的锁,如果需要加锁,可使用下列语句给查询语句加锁:

-- 给查询语句添加读锁(共享锁),只有当前事务能进行写操作,其他事务的读操作不受影响
SELECT * FROM app_user WHERE id=2 LOCK IN SHARE MODE;

-- 给查询语句添加写锁(排它锁),只有当前事务能进行读写操作,其他事务被阻塞
SELECT * FROM app_user WHERE id=2 LOCK IN SHARE MODE;

注意

  • 在使用InnoDB进行数据的更新操作时,如果where后面的条件没有索引,或者索引失效,会导致行锁升级为表锁。

  • 如果where后面是范围查询,即使不存对应的数据,只要在范围内的数据都会被加锁,我们称之为“间隙锁”;

    例如:where id<10,那么不管数据是否存在 id=2 的记录,它都会被加上行锁。

我们可以使用下列语句查询行锁的使用情况:

SHOW STATUS LIKE 'innodb_row_lock%';

image-20211024150515197

key 说明
Innodb_row_lock_current_waits 当前正在等待锁的数量
Innodb_row_lock_time 锁的总时长
Innodb_row_lock_time_avg 锁的平均时长
Innodb_row_lock_time_max 锁的最大时长
Innodb_row_lock_waits 等待锁的总次数

我们可根据以上参数,分析系统是否存在频繁进行锁等待、是否长时间锁等待,如果存在这些现象应该及时进行优化,提高sql的执行效率。

总结


InnoDB实现了行级锁,虽然行锁比较消耗资源,但是在并发能力上面比较优秀;如果在使用不当,行级锁可能升级为表锁,会让性能大幅下降甚至低于MyISAM引擎。

对于MySQL的锁:

  • 尽可能的让数据检索使用索引,避免行锁升级为表锁;
  • 合理设计索引,尽量缩小查询范围,减少被加锁的资源;
  • 尽量减少大范围查询和不连续查询,防止间隙锁;
  • 控制事务的大小,减少锁的资源量个时长;
  • 在满足页面的情况下,使用较低的事务隔离。

标签:加锁,行锁,查询,读锁,MySQL,操作,表锁
来源: https://www.cnblogs.com/lixingwu/p/15488106.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有