参考文章:https://blog.csdn.net/puhaiyang/article/details/72284702

一.mysql锁的结构图

如上图所示,针对mysql的innodb存储引擎,mysql锁包括了乐观锁和悲观锁。而悲观锁又包括共享锁和排它锁,共享锁/排它锁里又有行锁和表锁的实现,下面一个个说明他们的内容。

二.锁详解

1.乐观锁

乐观锁不是数据库自带的,需要我们自己去实现。乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了。

通常实现是这样的:在表中的数据进行操作时(更新),先给数据表加一个版本(version)字段,每操作一次,将那条记录的版本号加1。然后update的时候,where子句里,增加version值的判断,如果update返回的值是0,说明是版本号冲突,如果是1,则更新成功。

举个例子,例如要更新一个用户的数据

(1)查出用户的数据(假设根据uid查询),sql为:select id,name,mobile,version from user_db.t_user_info where uid=1024;

假设查出来的数据为

(2)假设要更新name字段为lisi,则sql为:update user_db.t_user_info set name='lisi',version=4 where uid=1024 and version=3;

如果这时候更新的结果是1,则更新成功;如果为0,则需要用户重新操作

2.悲观锁

悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟java中的synchronized很相似,所以悲观锁需要耗费较多的时间。另外与乐观锁相对应的,悲观锁是由数据库自己实现了的,要用的时候,我们直接调用数据库的相关语句就可以了。

mysql的悲观锁包括共享锁和排它锁。

先简单介绍什么是共享锁和排它锁:共享锁指的就是对于多个不同的事务,对同一个资源共享同一个锁;而排它锁与共享锁相对应,就是指对于多个不同的事务,对同一个资源只能有一把锁。

举个简单形象的例子来说明一下:共享锁就像是你家的大门钥匙,除了你有,你家人也有;而排它锁则像是试衣间,我进来了别人就不能进来了。

再来说说什么是行锁和表锁。

顾名思义,行锁获取数据库某一行的锁,而表锁就是获取某张表的锁。

下面更详细说明他们的用法。

(1)共享锁

刚刚说了,对于悲观锁,一般数据库已经实现了,共享锁也属于悲观锁的一种,所以,mysql自身对共享锁的功能是有实现的。

A.对于共享锁来说,一个事务获取了某一行的共享锁,则其他事务还可以继续获取这一行的共享锁,但是不能获取这行的排它锁。

B.如何获取某一行/表的共享锁。在select语句后面加 lock in share mode,即可获取共享锁。例如,sql为:

begin;
SELECT * from city where id = "1"  lock in share mode;

C.值得注意的一点,在有事务获取了共享锁之后,其他事务是不能做insert/update/delete,因为insert/update/delete语句,是自动加上排它锁的

D.如何判断获取的是行锁还是表锁

SELECT * from city where id = "1"  lock in share mode; 这个sql里,如果id这个字段带了索引,则获取的是行锁,否则获取的是表锁

ps:共享锁又称读锁

(2)排它锁

mysql自身对排它锁的功能也是有实现的

A.对于排它锁来说,一个事务获取了某一行的共享锁,其他事务不能再获取任何锁(包括共享锁和排它锁)

B.如何获取某一行/表的排它锁。在select语句后面加 for update,即可获取排它锁。例如,sql为:

begin;
SELECT * from city where id = "1"  lock in share mode;

C.如何判断获取的是行锁还是表锁和共享锁是一样的

D.insert/update/delete语句,是自动加上排它锁的

ps:排它锁又称写锁

(3)行锁

行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。

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

使用行级锁定的主要是InnoDB存储引擎。

(4)表锁

表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。

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

关于行锁和表锁,前面在共享锁和排它锁里已有说明,这里只提一点,慎用表锁,即select for update语句,where子句务必带上索引,否则极容易造成性能问题
————————————————
版权声明:本文为CSDN博主「无名草110」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mweibiao/java/article/details/80746453

mysql锁 转的更多相关文章

  1. mysql锁

    锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数 ...

  2. Mysql锁初步

    存储引擎 要了解mysql的锁,就要先从存储引擎说起. 常用存储引擎列表如下图所示: 最常使用的两种存储引擎: Myisam是Mysql的默认存储引擎.当create创建新表时,未指定新表的存储引擎时 ...

  3. mysql锁表机制及相关优化

    (该文章为方便自己查阅,也希望对大家有所帮助,转载于互联网) 1. 锁机制 当前MySQL支持 ISAM, MyISAM, MEMORY (HEAP) 类型表的表级锁,BDB 表支持页级锁,InnoD ...

  4. MySQL锁系列3 MDL锁

    http://www.cnblogs.com/xpchild/p/3790139.html   MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...

  5. 01 MySQL锁概述

    锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O 等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有 ...

  6. Mysql锁机制介绍

    Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  7. MySQL锁等待分析【2】

    MySQL锁等待分析[1]中对锁等待的分析是一步一步来的.虽然最后是分析出来了,可是用时是比较长的:理清各个表之间的关系后,得到如下SQL语句,方便以后使用 select block_trx.trx_ ...

  8. MySQL锁与MVCC

    --MySQL锁与MVCC --------------------2014/06/29 myisam表锁比较简单,这里主要讨论一下innodb的锁相关问题. innodb相比oracle锁机制简单许 ...

  9. MySQL锁总结

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/78 MySQL 锁基础 参考了何登成老师文章的结构MySQL 加 ...

  10. Mysql锁机制--并发事务带来的更新丢失问题

    Mysql 系列文章主页 =============== 刚开始学习 Mysql 锁的时候,觉得 Mysql 使用的是行锁,再加上其默认的可重复读的隔离级别,那就应该能够自动解决并发事务更新的问题.可 ...

随机推荐

  1. robotframework运行时后台报错UnicodeDecodeError,无日志输出

    解决办法: 1.找到对应位置的testrunner.py文件,修改字符集为GBK 2.删除同级目录下的testrunner.pyc 3.重启ride

  2. 搭建MQTT学习平台

    关于MQTT协议的介绍就不赘述了,网上资料非常多,直接入正题. MQTT协议的实现非常多,我选择了一个非常轻量级的开源项目来学习MQTT协议——mosquitto,官网:www.mosquitto.o ...

  3. 我是怎样通过个人项目成长为高级 JavaScript 开发者的

    大道理都是能用三两句话说清的 . 在我开发人员的职业生涯中,最好的决定之一就是不再满足于只做工具的使用者. 我决定创建我自己的工具,并不是为了卖钱,而是要了解这些技术的实际工作方式,并提升我的技术技能 ...

  4. oracle之二日志挖掘log miner

    日志挖掘 log miner 6.1 log miner的作用: 数据库恢复中有时会需要对Redo log进行分析, 要会使用log miner,以便确定要恢复的时间点或SCN 6.2 有两种日志挖掘 ...

  5. pycharm代码中批量粘贴内容的快捷键

    windows电脑中,竖向批量复制的快捷键:Alt

  6. [LeetCode]Mysql小本本

    常用方法 累加型题目,可以考虑使用笛卡尔积进行自表连接,连接后的表进行where条件进行筛选.group by分组操作. union:需要把两列作一列可以用union,union的两张表查询的字段不一 ...

  7. 手写spring

    体系结构 Spring 有可能成为所有企业应用程序的一站式服务点,然而,Spring 是模块化的,允许你挑选和选择适用于你的模块,不必要把剩余部分也引入.下面的部分对在 Spring 框架中所有可用的 ...

  8. k8s运行容器之deployment(三)

    deployment 我们已经知道k8s是通过各种controller来管理pod的生命周期.为了满足不同业务场景,k8s开发了Deployment.ReplicaSet.DaemonSet.Stat ...

  9. Java内部类使用场景和作用

    一.Java内部类的分类 Java内部类一般包括四种:成员内部类.局部内部类.匿名内部类和静态内部类 大多数业务需求,不使用内部类都可以解决,那为什么Java还要设计内部类呢. 二.内部类的使用场景 ...

  10. PHP变量覆盖漏洞小结

    前言 变量覆盖漏洞是需要我们需要值得注意的一个漏洞,下面就对变量覆盖漏洞进行一个小总结. 变量覆盖概述 变量覆盖指的是可以用我们自定义的参数值替换程序原有的变量值,通常需要结合程序的其他功能来实现完整 ...