云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

MySQL中的锁机制,按粒度分为行级锁,页级锁,表级锁,其中按用法还分为共享锁和排他锁.

行级锁

行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。

行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁.

特点

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

用法

共享锁(s 锁 读锁)

表级锁

表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。

最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为共享锁和排他锁.

特点

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

用法

共享锁(s 锁 读锁)

页级锁

页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。

表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁

特点

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

乐观锁和悲观锁的思想

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。

乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想。

其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache、hibernate、tair等都有类似的概念。

针对于不同的业务场景,应该选用不同的并发控制方式。所以,不要把乐观并发控制和悲观并发控制狭义的理解为DBMS中的概念,更不要把他们和数据中提供的锁机制(行锁、表锁、排他锁、共享锁)混为一谈。其实,在DBMS中,悲观锁正是利用数据库本身提供的锁机制来实现的。

悲观锁

在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。

如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度(悲观)

因此,在整个数据处理过程中,将数据处于锁定状态。

悲观锁的实现,往往依靠数据库提供的锁机制 (也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)

在数据库中,悲观锁的流程如下:

在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)

如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。具体响应方式由开发者根据实际需要决定。

如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。

其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常。

MySQL InnoDB中使用悲观锁

要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式

也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。set autocommit=0;

优点与不足

悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。

但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;

另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;

还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数

乐观锁

在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)是一种并发控制的方法。

它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。

在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。

乐观事务控制最早是由孔祥重(H.T.Kung)教授提出。

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突

所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测

如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。

相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。

数据版本,为数据增加的一个版本标识。当读取数据时,将版本标识的值一同读出,数据每更新一次,同时对版本标识进行更新。

当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的版本标识进行比对,如果数据库表当前版本号与第一次取出来的版本标识值相等,则予以更新,否则认为是过期数据。

实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳。

乐观锁使用CAS(Compare And Swep)操作保证数据一致性

使用版本号实现乐观锁

使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。并判断当前版本号是不是该数据的最新的版本号。

乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。

但如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题。

MySQL常用存储引擎的锁机制

MyISAM和MEMORY采用表级锁(table-level locking)

BDB采用页面锁(page-level locking)或表级锁,默认为页面锁

InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

Innodb中的行锁与表锁

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。

InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。

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

由于 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论 是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。

即便在条件中使用了索引字段,但是否使用索引来检索数据是由 MySQL 通过判断不同 执行计划的代价来决定的,如果 MySQL 认为全表扫效率更高,比如对一些很小的表,它就不会使用索引,这种情况下 InnoDB 将使用表锁,而不是行锁。因此,在分析锁冲突时, 别忘了检查 SQL 的执行计划,以确认是否真正使用了索引。

行级锁与死锁

MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。

而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。

在MySQL中,行级锁并不是直接锁记录,而是锁索引。

索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。

当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。

避免死锁,这里只介绍常见的三种:

如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会

在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率

对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文链接
本文为云栖社区原创内容,未经允许不得转载。

一文带你了解MySQL中的各种锁机制!相关推荐

  1. 一文带你了解 MySQL 中的各种锁机制!

    MySQL中的锁机制,按粒度分为行级锁,页级锁,表级锁,其中按用法还分为共享锁和排他锁. 行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁. 行级锁能大大减少数据库操作 ...

  2. mysql 获取距离当前最新的记录_一文带你了解 MySQL 中的各种锁机制!

    云栖号资讯:[点击查看更多行业资讯] 在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! MySQL中的锁机制,按粒度分为行级锁,页级锁,表级锁,其中按用法还分为共享锁和排他锁. 行级锁 ...

  3. 悲观锁和乐观锁_带你了解MySQL中的乐观锁与悲观锁

    在并发控制编程中锁是一个非常重要的概念,锁对于数据和业务一致性的保证起到关键作用,锁可以是程序层面的,也可以是数据库层面的,今天本文就通过MySQL来说明悲观锁与乐观锁两种常见的锁机制. 悲观锁 悲观 ...

  4. mysql中的get_lock锁机制解析

    GET_LOCK(key,timeout)  需要两个连接会话 RELEASE_LOCK(key)  锁是否释放,释放了返回1 IS_FREE_LOCK(key)  返回当前连接ID,表示名称为'xx ...

  5. 一文带你理解Java中Lock的实现原理

    转载自   一文带你理解Java中Lock的实现原理 当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题.java提供了两种方式来加锁,一种是关键字:synchron ...

  6. 复习Java小球游戏代码分享Java面试题MySQL中常用的锁生活【记录一个咸鱼大学生三个月的奋进生活】021

    记录一个咸鱼大学生三个月的奋进生活021 复习Java小球游戏 游戏界面的代码 小球运动线程的代码 运行游戏的代码 运行结果 代码分享 学习Java面试题(MySQL中常用的锁) 照片分享 复习Jav ...

  7. 【MySQL进阶】MySQL事务隔离与锁机制底层原理万字总结(建议收藏!!)

    [MySQL进阶]MySQL事务隔离与锁机制底层原理万字总结(建议收藏!!) 参考资料: 美团技术团队:Innodb中事务隔离级别和锁的关系 数据库的锁,到底锁的是什么? 阿里面试:说说一致性读实现原 ...

  8. Linux 2.6内核中新的锁机制--RCU [转]

    2005 年 7 月 01 日 本文详细地介绍了 Linux 2.6 内核中新的锁机制 RCU(Read-Copy Update) 的实现机制,使用要求与典型应用. 一. 引言 众所周知,为了保护共享 ...

  9. Linux 2.6内核中新的锁机制--RCU

    转载自: Linux 2.6内核中新的锁机制--RCU 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁(rwlock),它们使用起来非常简单,而且是一种 ...

最新文章

  1. 使用cmd将磁盘转化为GPT格式
  2. 如何衡量产品的用户体验?
  3. 计划订单号码范围用完导致MRP无法运行
  4. 6.4 你真的了解电子邮件系统的组成和结构吗?(SMTP、POP3、IMAP、MIME……)
  5. 柔性体没有应变_柔性应变和压力传感器
  6. Swift UISearchController
  7. 收藏 | OpenCV新手入门预处理
  8. TCP传输连接建立与释放详解
  9. C语言课后习题(48)
  10. 反射系数、驻波比、S参数之间的关系!
  11. composition API重构mixin实践
  12. 为什么我要弃用Snapchat?
  13. java余弦距离_使用TensorFlow实现余弦距离/欧氏距离(Euclideandistance)以及Attention矩阵的计算...
  14. 若x,y均定义为int型,z定义为double型,以下不合法的scanf函数调用语句是: A)scanf(“ %d%lx,%le“,x,y,z); B)scanf(“%2d * %d%lf“,
  15. 怎么从安卓设备转移数据到苹果_如何将数据从安卓手机转移到苹果手机
  16. 大众点评列表页采集思路,破解字体文件反爬(包含项目github 可用时间至2020-01-21)
  17. Autofill 实践
  18. Android中文乱码的分析与解决
  19. 山东哈斯精密机械有限公司
  20. 【整理】linux学习笔记(4)

热门文章

  1. 国嵌c语言深度,国嵌C语言3部全
  2. lnmp php文件访问不了,记一次lnmp环境下无法执行php文件
  3. linux 源码包编译,源码包编译安装
  4. mongodb 搜索速度_MongoDB数据库查询性能提高40倍的经历分享
  5. 钉钉功能介绍_平棉集团组织召开阿里钉钉办公系统基础功能培训会
  6. rfid阅读器的主要任务_RFID阅读器(读写器)的应用领域及其如何使用?
  7. python导出csv有引号_python – csv中的双引号元素不能用pandas读取
  8. 高大上的集团名字_那些刚改了“高大上”名字的学校,你知道都有哪些吗?蜻蜓AI小编来帮你科普一下...
  9. 算术溢出使用4字节值上的运算符_c语言程序设计的数据类型、运算符和表达式介绍...
  10. scp复制本地文件到远程服务器,scp 本地文件到远程服务器