解读mysql的for update用法

 更新时间:2023年08月29日 09:12:27   作者:韩师学子--小倪  
这篇文章主要介绍了解读mysql的for update用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

mysql的for update用法

for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁。

当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。

for update的使用场景

如果遇到存在高并发并且对于数据的准确性很有要求的场景,是需要了解和使用for update的。

比如涉及到金钱、库存等。一般这些操作都是很长一串并且是开启事务的。

如果库存刚开始读的时候是1,而立马另一个进程进行了update将库存更新为0了,而事务还没有结束,会将错的数据一直执行下去,就会有问题。

所以需要for upate 进行数据加锁防止高并发时候数据出错。

记住一个原则:一锁二判三更新

for update如何使用

使用姿势:

select * from table where xxx for update

for update的锁表

InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

例子:

假设表foods ,存在有id跟name、status三个字段,id是主键,status有索引。

例1: (明确指定主键,并且有此记录,行级锁)

SELECT * FROM foods WHERE id=1 FOR UPDATE;
SELECT * FROM foods WHERE id=1 and name='咖啡色的羊驼' FOR UPDATE;

例2: (明确指定主键/索引,若查无此记录,无锁)

SELECT * FROM foods WHERE id=-1 FOR UPDATE;

例3: (无主键/索引,表级锁)

SELECT * FROM foods WHERE name='咖啡色的羊驼' FOR UPDATE;

例4: (主键/索引不明确,表级锁)

SELECT * FROM foods WHERE id<>'3' FOR UPDATE;
SELECT * FROM foods WHERE id LIKE ‘3' FOR UPDATE;

for update的注意点

1.for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。

2.要测试for update的锁表情况,可以利用MySQL的Command Mode,开启二个视窗来做测试。

for update的疑问点

当开启一个事务进行for update的时候,另一个事务也有for update的时候会一直等着,直到第一个事务结束吗?

答:会的。除非第一个事务commit或者rollback或者断开连接,第二个事务会立马拿到锁进行后面操作。

如果没查到记录会锁表吗?

答:会的。表级锁时,不管是否查询到记录,都会锁定表。

for update和for update nowait区别(前者阻塞其他事务,后者拒绝其他事务)

for update锁住表或者锁住行,只允许当前事务进行操作(读写),其他事务被阻塞,直到当前事务提交或者回滚,被阻塞的事务自动执行

for update nowait 锁住表或者锁住行,只允许当前事务进行操作(读写),其他事务被拒绝,事务占据的statement连接也会被断开

mysql排它锁(FOR UPDATE) 场景

场景一 

当前使用for UPDATE查询,其他地方查询   --   其他地方也使用for UPDATE会堵塞,其他地方未使用for UPDATE不会堵塞

1. 当前A(不区分是否为事务里)使用for UPDATE查询

SELECT * FROM saas_employee_label_person where id = 1 for UPDATE

1.1 其他地方B(不在上一个连接里或事务里,不区分是否为事务里)使用for UPDATE 查询(需要获取锁)

SELECT * FROM saas_employee_label_person where id = 1 for UPDATE

会发生堵塞等待前一个A锁释放(A事务提交,或者A结束运行(A为非事务场景))

1.2 其他地方C(不区分是否为事务里)不使用for UPDATE 查询(无需获取锁)

SELECT * FROM saas_employee_label_person where id = 1

不会堵塞,可以查询

场景二 

当前使用for UPDATE查询,其他地方UPDATE更新   --   会堵塞等待

2. 当前A(不区分是否为事务里)使用for UPDATE查询

SELECT * FROM saas_employee_label_person where id = 1 for UPDATE

2.1 其他地方B(不区分是否为事务里)使用UPDATE更新数据

UPDATE saas_employee_label_person set employee_id = 1111 where id = 1;

会发生堵塞等待前一个A锁释放(A事务提交,或者A结束运行(A为非事务场景))

场景三 

当前事务使用UPDATE更新,其他地方使用for UPDATE查询   --   会堵塞等待

3. 当前事务A 使用UPDATE更新

BEGIN;
UPDATE saas_employee_label_person set employee_id = 11121 where id = 1;

3.1 其他地方B(不区分是否为事务里)使用 for UPDATE查询

SELECT * FROM saas_employee_label_person where id = 1 for UPDATE

会发生堵塞等待前一个事务A提交才可以获得锁

场景四

当前非事务使用UPDATE更新,其他地方使用for UPDATE查询   --   不会堵塞

4. 当前A(非事务下) 使用UPDATE更新

UPDATE saas_employee_label_person set employee_id = 11121 where id = 1;

4.1 其他地方B(不区分是否为事务里)使用 for UPDATE查询

SELECT * FROM saas_employee_label_person where id = 1 for UPDATE

不会堵塞,前一个update先执行完,所以不影响,这里一定是update先执行完在走for UPDATE查询的场景,否者就是场景二了

场景五

当前普通查询,其他地方使用for UPDATE查询   --   不影响,不会堵塞

总结

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

相关文章

  • 使用mysql workbench自动生成ER图的实现步骤

    使用mysql workbench自动生成ER图的实现步骤

    MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具,它是著名的数据库设计工具DBDesigne4的继任者,可以通过MySQL Workbench设计和创建新的数据库图示,本文给大家介绍了使用mysql workbench自动生成ER图的实现步骤,需要的朋友可以参考下
    2024-06-06
  • 安装mysq 5.7.20 解压版遇到的坑(推荐)

    安装mysq 5.7.20 解压版遇到的坑(推荐)

    最近有朋友说当mysql5.7.20解压版环境变量配置好后,根目录没有my.ini 也没有 my-default.ini文件,怎么处理这个问题呢,下面小编给大家带来了解决方案,大家可以参考下
    2017-11-11
  • Mysql全文搜索match against的用法

    Mysql全文搜索match against的用法

    全文检索在 MySQL 中就是一个 FULLTEXT 类型索引。FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、 VARCHAR 或 TEXT 列上创建
    2011-10-10
  • mysql存储过程中使用游标的实例

    mysql存储过程中使用游标的实例

    使用MYSQL存储过程,可以实现诸多的功能,下面将为您介绍一个MYSQL存储过程中使用游标的实例
    2014-01-01
  • mysql+Spring数据库隔离级别与性能分析

    mysql+Spring数据库隔离级别与性能分析

    数据库隔离级别与Spring配置事务的联系及性能影响,以下是个人理解,如果有瑕疵请及时指正
    2014-05-05
  • MySQL两种删除用户语句的区别(delete user和drop user)

    MySQL两种删除用户语句的区别(delete user和drop user)

    这篇文章主要介绍了MySQL两种删除用户语句的区别(delete user和drop user),帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-11-11
  • 详解MySQL 慢查询

    详解MySQL 慢查询

    这篇文章主要介绍了MySQL 慢查询的相关资料,文中讲解非常细致,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-07-07
  • mysql如何导出服务器内所有的数据库

    mysql如何导出服务器内所有的数据库

    这篇文章主要介绍了mysql如何导出服务器内所有的数据库问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 浅谈慢SQL优化之索引的作用

    浅谈慢SQL优化之索引的作用

    本文针对 MySQL 数据库的 InnoDB 存储引擎,介绍其中索引的实现以及索引在慢 SQL 优化中的作用,本文主要讨论不同场景下索引生效与失效的原因,感兴趣的小伙伴可以跟着小编一起来探讨
    2023-05-05
  • Mysql8.0密码问题mysql_native_password和caching_sha2_password详解

    Mysql8.0密码问题mysql_native_password和caching_sha2_password详解

    这篇文章主要介绍了Mysql8.0密码问题mysql_native_password和caching_sha2_password,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08

最新评论