热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

详解数据库锁机制和原理

开足码力,码动人生,微信搜索【程序员大帝】,关注这个一言不合就开车的的代码界老司机本文GitHub上已经收录https:github.co

开足码力,码动人生,微信搜索【 程序员大帝 】,关注这个一言不合就开车的的代码界老司机
本文 GitHub上已经收录 https://github.com/BeKingCoding/JavaKing , 一线大厂面试核心知识点、我的联系方式和技术交流群,欢迎Star和完善



前言


在座的朋友们,你们的时间够用吗?想要成为一个成功的人吗?如果你们都有这样的疑惑,那就保持一刻谦虚的心态,跟着罗老师学习时间管理吧!


在这里插入图片描述

毕竟时间管理大师是一个用户访问多个资源,今天咱们来讲讲当多个用户并发访问同一个资源时的情况

在数据库中,如果多个事务同时对一个数据进行操作,并发的操作若不加控制,可能会读取和存储不正确的数据,破坏数据库的一致性、脏读、不可重复读、幻读等、甚至可能产生死锁。

为了解决这个问题,加锁是一个非常重要的技术,对实现数据库并发控制是一个好的方案。

简单说,当一个执行 sql 语句的事务想要操作表记录之前,先向数据库发出请求,对你访问的记录加锁,在这个事务释放这个锁之前,其他事务不能对这些数据进行更新操作。

本文将基于 MySQL,介绍数据库锁机制,相信大家耐心看了之后肯定有收获,码字不易,别忘了「在看」,「转发」哦。


  • 锁的类型
  • MyISAM 锁机制
  • InnoDB 锁机制

正文


01 锁的类型

从对数据的操作粒度来划分,MySQL 大致可归纳为 3 种锁。


  • 表级锁

表级别的锁定是 MySQL 各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。

所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。

当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并发大度大打折扣。


  • 行级锁

行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。

由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。

虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。


  • 页级锁

页面锁会去锁定一页的数据,我们知道 MySQL 的索引本身是由 B+ 树实现的。

每个叶子节点的单位页,叶子节点上面存放了多个记录行,数据存储是按照一页一页来的,每次锁定一页的数据,其实就是相邻的数据,开销和加锁时间界于表锁和行锁之间。

页级锁也会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。


02 MyISAM锁机制

MyISAM引擎只提供表锁。

在执行查询语句( SELECT )前,会自动给涉及的表加读锁,此时允许其他用户对同一表的读操作。但会阻塞对同一个表的写操作。

在执行更新操作( UPDATE、DELETE、INSERT 等)前,会自动给涉及的表加写锁,此时会阻塞其他用户对同一个表的读操作和写操作。


03 InnoDB锁机制

InnoDB 支持表锁、行锁,实际上InnoDB 是通过给索引项加锁,来实现行锁的。

只有查询数据时,检索条件走索引才可以使用行级锁,否则 InnoDB 将使用表锁。

在实际开发中,要特别注意 InnoDB 这一特性,不然,可能造成大量的锁冲突,从而影响并发!!!

InnoDB使用索引的条件

(1)在不通过索引条件查询的时候,InnoDB 确实使用的是表锁,而不是行锁。

(2)行锁是针对索引加锁,不是针对记录加的锁。即使访问的是不同行,但如果它们索引相同,还是会出现锁冲突。

(3)当表中含有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行。

(4)即使在条件中使用了索引,但是否使用索引来检索数据是由 MySQL 通过判断不同执行计划的代价决定的。如果 MySQL 认为全表扫描效率更高,比如很小的表,也不会使用索引,此时 InnoDB 将使用表锁,而不是行锁。因此,在分析锁冲突的时候,不要忘记检查 SQL 的执行计划,以确定是否真正使用了索引。

在默认的可重复读隔离级别下:

执行查询语句( SELECT )前,由于 MVCC(多版本控制)的方式,什么锁都不会加。

在执行更新操作( UPDATE、DELETE、INSERT 等)前,会自动给涉及的行加写锁,此时会阻塞其他用户的写操作,但是通过 MVCC(多版本控制)的方式允许读操作。


04 总结

通过这篇文章,基于MySQL,为大家介绍了数据库的锁机制。针对不同情况,什么时候使用锁,锁到底生不生效是大家需要关注的问题。




Offer收割机》系列持续更新,也会定期分享互联网常用技术栈相关的文章,GitHub 上已经收录 https://github.com/BeKingCoding/JavaKing ,讲解一线大厂面试要求的核心知识点、并有对标阿里P7级别的成长体系脑图,欢迎加入技术交流群,我们一起有点东西。




在这里插入图片描述



我是一言不合就开车的代码界老司机无忌。创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
在这里插入图片描述


推荐阅读
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • MySQL插入数据的四种方式及安全性分析
    本文介绍了MySQL插入数据的四种方式:插入完整的行、插入行的一部分、插入多行和插入查询结果,并对其安全性进行了分析。在插入行时,应注意字段的定义和赋值,以提高安全性。同时指出了使用insert语句的不安全性,应尽量避免使用。建议在表中定义相关字段,并根据定义的字段赋予相应的值,以增加插入操作的安全性。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
author-avatar
0鞋包控0
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有