Mysql中的select ...for update

 更新时间:2023年08月29日 11:01:18   作者:哇~是小菜呀  
这篇文章主要介绍了Mysql中的select ...for update用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Mysql select ...for update

这几天遇到了select … for update的sql语句,决定整理一下mysql的两种锁机制。

Mysql数据库有两种锁,一种是共享锁,一种是排他锁,这两种锁是针对InnoDB的,如果是MyISM不是这样的锁机制。

共享锁和拍他锁的锁对象是主键!

共享锁(读锁,S锁)

select … from … lock in share mode

多个事务共享一把锁,但是只能读,不能修改

当有事务拿到共享锁的时候且锁未释放时,另一个事务不能去修改加锁的数据。

在这里插入图片描述

共享锁的最大特点是可以共享,多个事务可以同时获取锁并且读到数据,并且,在锁没有释放时,数据不能被修改,这样可以避免数据库脏读和不可重复读的问题。

排他锁(互斥锁,写锁,X锁)

select … for update;

排他锁 不能被多个事务共享,如果一个事务获取了一行数据的排他锁,那么其他事务就不能获取这行数据的锁,包括共享锁和排他锁。

获取到排他锁的事务可以对数据进行读取和修改,事务提交后,锁释放。

在这里插入图片描述

演示

创建一张用于测试的表格

CREATE TABLE `emipe_user_entity` (
  `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '主键',
  `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户名',
  `pass_word` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户密码',
  `status` int(11) DEFAULT NULL COMMENT '用户状态',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

使用InnoDB储存引擎,InnoDB既支持行级锁,又支持表级锁,默认情况下采用行级锁

MySQL InnoDB引擎默认的update,delete,insert语句会自动给涉及到的数据加上排他锁。

为测试的表格存入数据

INSERT INTO `emipe_user_entity` VALUES ('1', '小红帽', '123456', 0);
INSERT INTO `emipe_user_entity` VALUES ('2', '路人甲', '523456', 0);

共享锁

事务A:获取共享锁,但不提交事务

begin;
select * from emipe_user_entity where id = 1 lock in share mode;

事务B:获取共享锁,可以查询到数据

select * from emipe_user_entity where id = 1 lock in share mode;

事务C:尝试修改带有共享锁的数据,报错

update emipe_user_entity set pass_word = '222222' where id = 1;

结果:

在这里插入图片描述

事务C首先会等待共享锁释放,待锁释放后,可以对改数据进行修改,由于事务A一直没有释放锁,在长久的等待后,事务C抛错:

Lock wait timeout exceeded;try restarting trasacrtion.

等待锁超时;尝试重启这个事务

排他锁

事务A:获取排他锁进行查询,事务不提交

begin;
select * from emipe_user_entity where id = 1 for update;

事务B:尝试获取排他锁,被阻塞

select * from emipe_user_entity where id = 1 for update;

事务C: 尝试获取共享锁,被阻塞

select * from emipe_user_entity where id = 1 lock in share mode;

事务D:在不使用锁的情况下,可以查询数据

select * from emipe_user_entity where id = 1;
-- 查询成功

普通的查询语句没有任何锁机制。

总结

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

相关文章

  • MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别整理

    MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别整理

    这篇文章主要介绍了MySQL 4.1/5.0/5.1/5.5/5.6各版本的主要区别整理,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-08-08
  • MySQL高可用与扩展方式

    MySQL高可用与扩展方式

    本文深入探讨了MySQL的高可用和扩展策略,包括主从复制与读写分离、MySQL集群与负载均衡、分布式数据库架构以及数据库的水平与垂直扩展,每个主题都提供了详细的代码示例,帮助读者理解和应用这些技术,通过这些策略,可以有效地提高MySQL数据库的性能、吞吐量和可用性
    2025-03-03
  • MySql执行流程与生命周期详解

    MySql执行流程与生命周期详解

    当你执行一次MySQL查询时,有没有仔细想过,在查询结果返回之前,经过了哪些步骤呢?这些步骤有可能消耗了超出想象的时间和资源。因此,在对MySQL的查询进行优化之前,应该了解一下MySQL查询的生命周期
    2022-09-09
  • mysql如何实现多行查询结果合并成一行

    mysql如何实现多行查询结果合并成一行

    利用函数:group_concat(),实现一个ID对应多个名称时,原本为多行数据,把名称合并成一行
    2013-12-12
  • 详解grep获取MySQL错误日志信息的方法

    详解grep获取MySQL错误日志信息的方法

    在本篇文章中小编给大家整理了关于通过grep 获取MySQL错误日志信息的方法的相关知识点内容,有需要的朋友们跟着学习下。
    2018-09-09
  • MySQL修改时区的方法小结

    MySQL修改时区的方法小结

    这篇文章主要介绍了MySQL修改时区的方法,总结分析了三种常见的MySQL时区修改技巧,包括命令行模式、配置文件方式及代码方式,需要的朋友可以参考下
    2016-05-05
  • 通过两种方式增加从库——不停止mysql服务

    通过两种方式增加从库——不停止mysql服务

    现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库。前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作
    2015-11-11
  • 一文教你学会定位线上MySQL锁超时问题

    一文教你学会定位线上MySQL锁超时问题

    这篇文章主要介绍了一文教你学会定位线上MySQL锁超时问题,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • linux下mysql自动备份数据库与自动删除临时文件

    linux下mysql自动备份数据库与自动删除临时文件

    mysql自动备份数据库与自动删除临时文件,有需要的朋友可以参考下
    2013-02-02
  • 详细介绍windows下MySQL安装教程

    详细介绍windows下MySQL安装教程

    这篇文章主要给大家介绍的是windows下MySQL安装教程,其实好多公司,数据库的面试题都是不可避免的,甚至一些前端工程师面试的时候都避免不了被询问到和数据库有关的一些问题。下面就从最基础的安装教程开始,需要的朋友可以参考一下
    2021-11-11

最新评论