一、前言

对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答。

MySQL常用引擎有MyISAM和InnoDB,而InnoDB是mysql默认的引擎。MyISAM不支持行锁,而InnoDB支持行锁和表锁。

相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。

MySQL大致可归纳为以下3种锁:

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

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

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

如何加锁?

MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。

显式加锁:

上共享锁(读锁)的写法: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在执行查询语句(select)前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁。

MySQL的表级锁有两种模式:

表共享读锁

表独占写锁

读锁会阻塞写,写锁会阻塞读和写

对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。

对MyISAM表的写操作,会阻塞其它进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。

MyISAM不适合做写为主表的引擎,因为写锁后,其它线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞

三、行锁

会出现死锁,发生锁冲突几率低,并发高。

在MySQL的InnoDB引擎支持行锁,与Oracle不同,MySQL的行锁是通过索引加载的,也就是说,行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描,行锁则无法实现,取而代之的是表锁,此时其它事务无法对当前表进行更新或插入操作。

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

如果在一条select语句后加上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用户消费,service层先查询该用户的账户余额,若余额足够,则进行后续的扣款操作;这种情况查询的时候应该对该记录进行加锁。

否则,B用户在A用户查询后消费前先一步将A用户账号上的钱转走,而此时A用户已经进行了用户余额是否足够的判断,则可能会出现余额已经不足但却扣款成功的情况。

为了避免此情况,需要在A用户操作该记录的时候进行for update加锁

扩展:间隙锁

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内并不存在的记录,叫做间隙

InnoDB也会对这个"间隙"加锁,这种锁机制就是所谓的间隙锁

-- 用户A

update user set count=8 where id>2 and id<6

-- 用户B

update user set count=10 where id=5;

如果用户A在进行了上述操作后,事务还未提交,则B无法对2~6之间的记录进行更新或插入记录,会阻塞,当A将事务提交后,B的更新操作会执行。

建议:

尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁

合理设计索引,尽量缩小锁的范围

尽可能减少索引条件,避免间隙锁

尽量控制事务大小,减少锁定资源量和时间长度

到此这篇关于MySQL 行锁和表锁的含义及区别详解的文章就介绍到这了,更多相关MySQL 行锁和表锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

mysql某个表被行锁了_MySQL 行锁和表锁的含义及区别详解相关推荐

  1. mysql 脏读 不可重复读 幻读_mysql事务隔离级别/脏读/不可重复读/幻读详解

    一.四种事务隔离级别 1.1read uncommitted 读未提交 即:事务A可以读取到事务B已修改但未提交的数据. 除非是文章阅读量,每次+1这种无关痛痒的场景,一般业务系统没有人会使用该事务隔 ...

  2. mysql 有ntext_深入char、varchar、text和nchar、nvarchar、ntext的区别详解

    很多开发者进行数据库设计的时候往往并没有太多的考虑char, varchar类型,有的是根本就没注意,因为存储价格变得越来越便宜了,忘记了最开始的一些基本设计理论和原则,这点让我想到了现在的年轻人,大 ...

  3. mysql int(3)与int(11)的区别详解

    这篇文章主要介绍了mysql int(3)与int(11)的区别详解的相关资料,需要的朋友可以参考下 mysql int(3)与int(11)的区别 总结,int(M) zerofill,加上zero ...

  4. linux上传文件命令ftp put,Linux ftp 命令行中下载文件get与上传文件put的命令应用详解...

    介绍:从本地以用户anok登录的机器192.168.0.16上通过ftp远程登录到192.168.0.6的ftp服务器上,登录用户名是peo.以下为使用该连接做的实验. 查看远程ftp服务器上用户pe ...

  5. linux get与put,科技常识:Linux ftp 命令行中下载文件get与上传文件put的命令应用详解...

    今天小编跟大家讲解下有关Linux ftp 命令行中下载文件get与上传文件put的命令应用详解 ,相信小伙伴们对这个话题应该也很关注吧,小编也收集到了有关Linux ftp 命令行中下载文件get与 ...

  6. decimal类型对象里面定义什么类型_MySQL中Decimal类型和Float Double的区别(详解)

    MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...

  7. mysql行锁还需要乐观锁吗_mysql行锁、表锁。乐观锁,悲观锁

    锁定用于确保事务完整性和数据库一致性. 锁定可以防止用户读取其他用户正在更改的数据,并防止多个用户同时更改相同的数据. 如果不使用锁定,数据库中的数据可能在逻辑上变得不正确,而针对这些数据进行查询可能 ...

  8. mysql更新锁机制_mysql查询更新时的锁表机制分析

    欢迎进入Linux社区论坛,与200万技术人员互动交流 >>进入 为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁 ...

  9. mysql 行级锁 索引_mysql 行级锁 索引唯一值

    做项目时由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统.假设 id=1 的这本书库存为 1 ,但是有 2 个人同时来借这本书,此处的逻辑为 Select rest ...

最新文章

  1. JQuery判断radio是否选中,获取选中值
  2. c#中chart绘制曲线,柱状图等
  3. ObjectOutputStream 和 ObjectInputStream类的简单介绍,及运用。
  4. Android 自动扫描歌曲,Android扫描本地音乐文件开发案例分享
  5. 【分享】哪些句子一眼就会让你爱上
  6. 6 万出头的北京房价,程序员如何靠自己安家?
  7. Sublime Text3 直接运行js调试控制台
  8. SQL:postgresql中COALESCE函数
  9. psd做成html叫切图吗,第一章 PSD网页切图制作HTML全过程教程.pdf
  10. 记录一次win10美化之路
  11. 2021年机修钳工(初级)免费试题及机修钳工(初级)模拟考试题
  12. 什么是线程安全性,如何保证线程安全*
  13. maven html项目自动版本控制(时间戳) com.google.code.maven-replacer-plugin插件 前端代码自动添加版本号
  14. 深入浅出 RxJS 核心原理(源码实现)
  15. C#实现Winform间的数据交互的三种方法
  16. 2021年危险化学品生产单位安全生产管理人员最新解析及危险化学品生产单位安全生产管理人员免费试题
  17. 文献综述在论文中的应用
  18. 学习笔记(16):重叠元素
  19. 华为手机将微信聊天记录迁移到 SD卡
  20. css中一个一个字显示效果

热门文章

  1. AWS 专家教你快速使用 Spring Boot 和 DJL!
  2. iPhone11 全线降价;哈啰出行否认大量裁员;LineageOS 17.1 发布| 极客头条
  3. 一文足以了解什么是 Java 中的锁
  4. 这类程序员成为百度、阿里宠儿,分分钟秒杀众应届毕业生
  5. 假期还剩 2 天,Python 爬取途牛网,揭秘哪里人少景美!
  6. 抛弃 VS Code 我还能用啥编辑器?| 技术头条
  7. Hacker News 12 月招聘趋势:React 已连续霸榜 19 个月
  8. Windows 10 终于干掉了 Windows 7!
  9. 腾讯专利仅次谷歌;​苹果或将 iPhone 订单转给和硕;​Uber 接受比特币支付 | 极客头条...
  10. 为何 iOS 越来越偏爱 Swift?