关于for update和lock in share mode的区别及说明

 更新时间:2023年08月29日 14:57:47   作者:小淼同学  
这篇文章主要介绍了关于for update和lock in share mode的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

lock in share mode 就是共享锁

如果事务对某行数据加上共享锁之后,可进行读写操作;其他事务可以对该数据加共享锁,但不能加排他锁,且只能读数据,不能修改数据。

某个事物想进行修改数据操作,那他必须等其他事物的共享锁都释放完毕才能进行修改操作

for update 排他锁,就是行锁

如果事务对数据加上排他锁之后,则其他事务不能对该数据加任何的锁。

获取排他锁的事务既能读取数据,也能修改数据。

注:普通 select 语句默认不加锁,而CUD操作默认加排他锁。

例子

下面例子的前提都是针对同一行数据。

1.同一行数据为前提,两个事物都进行共享锁查询

2.同一行数据为前提,一个事物进行共享锁查询,另一个事物进行修改

第一个占有着共享锁,第二个事物没法更新,必须等第一个事物释放才能进行更新

3.同一行数据为前提,一个进行共享锁查询,另一个先进行共享锁查询,然后update

同第二种,修改的事物就一直在转圈圈,等待事物1提交。事物1不提交,那事物2只能等到超时返回错误。

4.同一行数据为前提,当事物一获得共享锁,另一个事物是否可以获得排它锁

答案是不能,事物二就一直转圈圈,等待1的释放

结论:同一行数据为前提,当一个事物获得共享锁,另一个事物可以获得共享锁进行读操作,但不能进行修改操作,想要修改必须等其他的共享锁释放完毕。还有一个事物获得了共享锁,另一个事物不能获得排它锁

5.同一行数据为前提,一个事物获取到排他锁,另一个事物进行查询

结果是可以的,一个获取排它锁,另一个进行普通查询

6.同一行数据为前提,一个事物获取到排他锁,另一个事物进行共享锁的获取

结果如图2,爱的魔力转圈圈,就一直卡在那里

7.同一行数据为前提,一个事物获取排它锁,另一个事物是否可以进行修改

结果如图2,爱的魔力转圈圈,就一直卡在那里

8.同一行数据为前提,一个事物获取排它锁,另一个是否可以获取排它锁

结果如图2,爱的魔力转圈圈,就一直卡在那里

结论:当前事务获取某行数据排他锁后,其他事务是否可以对该行数据进行读写操作和获取共享锁:其他事务可以读,不可以获取共享锁,不可以写

这里再给读者科普一点,行锁和索引的关系:查询字段未加索引(主键索引、普通索引等)时,使用表锁

注:InnoDB行级锁基于索引实现。

未加索引时,两种行锁情况为(使用表锁):

  • 事务1获取某行数据共享锁,其他事务可以获取不同行数据的共享锁,不可以获取不同行数据的排他锁
  • 事务1获取某行数据排他锁,其他事务不可以获取不同行数据的共享锁、排他锁

加索引后,两种行锁为(使用行锁):

  • 事务1获取某行数据共享锁,其他事务可以获取不同行数据的排他锁
  • 事务1获取某行数据排他锁,其他事务可以获取不同行数据的共享锁、排他锁

表结果:

CREATE TABLE `pf_banner` (
  `id` bigint(22) NOT NULL AUTO_INCREMENT,
  `num` int(11) DEFAULT NULL,
  `title` varchar(80) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  `img` varchar(255) DEFAULT NULL,
  `status` tinyint(4) DEFAULT '1' COMMENT '状态 1:显示 -1不显示',
  `create_time` datetime DEFAULT NULL,
  `modify_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='banner位图片'

例子

1.未加索引,事务1获取某行数据共享锁,事务2更新不同行数据阻塞:

2.未加索引,事务1获取某行数据共享锁,事务2获取不同行数据共享锁成功:

3.未加索引,事务1获取某行数据排他锁,事务2获取不同行数据共享锁阻塞:

4.未加索引,事务1获取某行数据排他锁,事务2获取不同行数据排他锁阻塞:

加索引后表结构:

CREATE TABLE `pf_banner` (
  `id` bigint(22) NOT NULL AUTO_INCREMENT,
  `num` int(11) DEFAULT NULL,
  `title` varchar(80) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  `img` varchar(255) DEFAULT NULL,
  `status` tinyint(4) DEFAULT '1' COMMENT '状态 1:显示 -1不显示',
  `create_time` datetime DEFAULT NULL,
  `modify_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_num` (`num`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='banner位图片'

1.加索引后,事务1获取某行数据共享锁,事务2可以更新不同行数据:

2.加索引后,事务1获取某行数据共享锁,事务2获取不同行数据共享锁成功:

3.加索引后,事务1获取某行数据排他锁,事务2获取不同行数据排他锁成功:

4.加索引后,事务1获取某行数据排他锁,事务2获取不同行数据共享锁成功:

科普小知识2:索引数据重复率太高会导致全表扫描:当表中索引字段数据重复率太高,则MySQL可能会忽略索引,进行全表扫描,此时使用表锁。可使用 force index 强制使用索引。

操作步骤

1.事务1,执行鼠标选中的内容

2.事物2,执行鼠标选中的内容

你会发现事物2会一直转圈圈,其实在执行update的时候,已经是表锁了。导致事物2 进行行锁的时候,需要等待事物1的释放

现在,我们使用强制锁进行更新操作。

当你使用强制索引的时候,就会发现更新成功了。

当然数据重复降低,也是能成功的

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL系列关于NUll值的经验总结分析教程

    MySQL系列关于NUll值的经验总结分析教程

    这篇文章主要为大家介绍了MySQL系列关于NUll值的一些经验总结分析,关于null值的影响作用以及为什么会出现null值的原因等等问题的解析
    2021-10-10
  • 提高MySQL中InnoDB表BLOB列的存储效率的教程

    提高MySQL中InnoDB表BLOB列的存储效率的教程

    这篇文章主要介绍了提高MySQL中InnoDB表BLOB列的存储效率的教程,InnoDB的优化在MySQL的优化研究中也是一个非常热门的课题,需要的朋友可以参考下
    2015-05-05
  • MySQL为id选择合适的数据类型

    MySQL为id选择合适的数据类型

    为 id 列选择一个好的数据类型非常重要,id 列会经常用于做比较(例如联合查询的条件),以及用于查找其他列。而且,id 也经常用于外键。因此,id 列的数据类型不仅仅关系自身数据表,也关系到与之关联的其他数据表。因此,id 用何种数据类型就显得十分重要
    2021-06-06
  • mysql特殊语法insert into .. on duplicate key update ..使用方法详析

    mysql特殊语法insert into .. on duplicate key update ..使用方

    在我们的日常开发中经常会遇到过这样的情景,查看某条记录是否存在,不存在的话创建一条新记录,存在的话更新某些字段,下面这篇文章主要给大家介绍了关于mysql特殊语法insert into .. on duplicate key update ..使用方法的相关资料,需要的朋友可以参考下
    2023-04-04
  • MySQL定时备份之使用Linux下的crontab定时备份实例

    MySQL定时备份之使用Linux下的crontab定时备份实例

    这篇文章主要介绍了使用Linux下的crontab进行MySQL定时备份的例子,需要的朋友可以参考下
    2014-04-04
  • MYSQL 数据库导入导出命令

    MYSQL 数据库导入导出命令

    在不同操作系统或MySQL版本情况下,直接拷贝文件的方法可能会有不兼容的情况发生。所以一般推荐用SQL脚本形式导入。下面分别介绍两种方法。
    2010-11-11
  • mysql 5.7.20 win64 安装及配置方法

    mysql 5.7.20 win64 安装及配置方法

    这篇文章主要介绍了mysql 5.7.20 win64 安装及配置方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-11-11
  • 简述MySql四种事务隔离级别

    简述MySql四种事务隔离级别

    这篇文章主要介绍了MySql四种隔离级别,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-08-08
  • MySQL Count函数使用教程

    MySQL Count函数使用教程

    这篇文章主要介绍了MySQL Count函数,COUNT()是一个聚合函数,返回指定匹配条件的行数。开发中常用来统计表中数据,全部数据,不为NULL数据,或者去重数据
    2022-12-12
  • MySQL 的覆盖索引与回表的使用方法

    MySQL 的覆盖索引与回表的使用方法

    这篇文章主要介绍了MySQL 的覆盖索引与回表的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论