首页 > 数据库 >Mysql 悲观锁

Mysql 悲观锁

时间:2023-07-20 11:13:46浏览次数:48  
标签:product 行锁 索引 悲观 Mysql 表锁 id

1.mysql的悲观锁 概念

悲观锁[Pessimistic Concurrency Control]指的是 在操作数据的时候悲观的认为数据会发生冲突, 所以在每次操作的时候都直接把数据给锁住 ,这样其他的线程就只能阻塞住 无法操作, 所以悲观锁比较耗费时间, 一般悲观锁都是借助 数据库锁机制 在java中 synchronized 就是悲观锁 同一时刻只有一个线程能拿到锁 执行

2.悲观锁的类别

基于数据操作的 类型 分类

悲观锁分为 排他锁 和 共享锁

  • 排他锁[exclusive locks]: 简称 写锁, 是指 一个事物中获取了排他锁后 其他事物就无法获取锁进行读取和修改操作了,获取排他锁的事务可以对数据行读取和修改。
  • 共享锁[shared locks]: 简称 读锁, 是指 多个事物可以对同一数据共享一把锁 都能访问读取到数据, 但是无法修改

2.1 排他锁

mysql 中可以使用 select ... for update 来应用悲观锁

select * from product_lock where id = 1 for update;

如果发生并发,同一时间只有一个线程可以开启事务并获得 id=1 的锁,其它的事务必须等本次事务提交/回滚之后才能执行。这样可以保证当前的数据不会被其它事务修改。

 

 

 

 

2.2 共享锁

mysql 中可以使用 lock in share mode 来给语句添加 共享锁

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

如果发生并发,如果有一个事物开启了 某数据的共享锁, 其他事物可以获取到这个数据的锁 进行读取 但是无法更新这个数据

 

 

 

 

 

 

3. 悲观锁 表锁行锁 注意事项

在使用悲观锁的时候 需要注意 表锁和行锁 以及死锁的情况, 默认情况MySQL InnoDB 默认行级锁 但是 行级锁都是基于索引的 如果使用不当会导致 行锁变成表锁 降低性能

行锁条件

  1. where 后面查询条件字段 必须是 主键索引/索引
  2. 条件必须是 = in 这种精确的 不能是 like 和 != 这种

3.1 未添加索引的字段查询

可以看到 因为行锁是基于索引的 如果没有索引 则是 表锁

 

 

 

 

 

 

3.2 添加了索引的字段查询

下面把 product_code 给添加了 索引 可以发现就是行锁

 

 

 

 

 

 

3.3 条件不是 精确

非精确查询 因为不能走索引 所以也不是行锁

# 都是表锁
select * from product_lock where product_code like '%01' for update;
# 都是表锁
select * from product_lock where product_code != '1001' for update; 

3.4 死锁

死锁是 两个事物中 都先持有一个数据的锁, 然后互相再访问对方数据的锁 导致死锁,

如下 终端1 先获取了 id =1 的锁 , 终端2 也先获取了id =2的锁 , 但是后续 终端1 想去获取id=2的锁 终端2 想去获取id = 1的数据 此时就产生了死锁现象

 

 

 

 

建议: 让不同的 session 加锁的要有次序

总结

本篇主要介绍了 mysql 中悲观锁的一些基本的概念, 并且对悲观锁的分类 分别进行了演示, 最后总结了使用悲观锁的注意实现 包括 表锁和行锁 以及死锁的情况 , 需要注意 mysql InnoDB 默认行级锁 , 行锁是基于索引的 需要注意条件是精确的并且使用上了索引 否则会变成表锁

标签:product,行锁,索引,悲观,Mysql,表锁,id
From: https://www.cnblogs.com/tianxc66/p/17567750.html

相关文章

  • mysql清空表 怎么阻断
    项目方案:阻断MySQL清空表操作简介在某些情况下,我们可能需要阻断MySQL数据库中的表清空操作,以防止误操作或者恶意操作导致数据丢失。本项目方案将介绍如何通过代码实现阻断MySQL清空表操作的功能。技术选型编程语言:Python数据库:MySQLPython库:pymysql环境配置安装Python和......
  • mysql写入数据慢
    MySQL写入数据慢的原因及优化方法MySQL是一种非常流行的关系型数据库,广泛应用于各种应用程序和网站中。然而,有时我们会遇到MySQL写入数据慢的问题。本文将介绍可能导致写入数据慢的原因,并提供一些优化方法来改善性能。1.原因分析1.1硬件问题首先,我们需要检查硬件是否存在问题......
  • mysql切库
    MySQL切库介绍在开发中,我们经常需要连接多个数据库进行操作,这就需要在程序中实现数据库的切换。MySQL作为一种常用的关系型数据库管理系统,提供了多种方式来实现切库操作。本文将介绍几种常用的切库方式,并提供相应的代码示例。方法一:使用USE语句在MySQL中,可以使用USE语句来切换......
  • mysql启动指定my.cnf
    MySQL启动指定my.cnf文件在MySQL中,my.cnf是用于配置MySQL服务器的配置文件。默认情况下,MySQL会在一些预定义的位置(如/etc/my.cnf)中寻找my.cnf文件。但是,有时候我们希望在启动MySQL服务器时使用不同的配置文件,这时就需要指定使用特定的my.cnf文件。以下是通过命令行启动MySQL服务......
  • mysql小数位数设置
    MySQL小数位数设置详解在MySQL中,小数位数是指在浮点数字段中保留的小数位数。它决定了存储和显示浮点数时的精度。MySQL允许在表定义中指定小数位数,并且还提供了一些函数和操作符来处理浮点数的小数位数。本文将介绍MySQL中小数位数的设置和使用。1.定义小数位数在MySQL中,我们......
  • mysql显示小数点后10位
    MySQL显示小数点后10位在MySQL中,小数数据类型是一种用于存储带有小数部分的数值的数据类型。默认情况下,MySQL会根据实际数值的精度来决定小数的显示位数。如果你想要在查询结果中显示小数点后10位,可以通过设置查询语句或更改数据库会话的设置来实现。查询语句中显示小数点后10位......
  • mysql批量更新数据的创建时间
    MySQL批量更新数据的创建时间实现流程在MySQL中,要批量更新数据的创建时间,可以通过以下步骤完成:步骤操作连接数据库使用代码连接MySQL数据库,获取数据库连接对象查询需要更新的数据使用SQL语句查询需要更新的数据批量更新数据遍历查询结果,使用代码更新每条数据的......
  • mysql位运算用索引么
    MySQL位运算用索引吗?引言在MySQL中,位运算是一种常用的操作。但是,对于位运算是否能够使用索引来提高查询性能,对于刚入行的开发者来说可能会感到困惑。本文将为大家介绍位运算在MySQL中使用索引的流程和相关代码示例。流程下面是使用索引进行位运算的一般流程:步骤描述1......
  • mysql批量导入excel数据
    Mysql批量导入Excel数据教程1.整体流程首先,我们来看一下整个批量导入Excel数据的流程。具体步骤如下:步骤描述1读取Excel文件2解析Excel文件数据3创建数据库连接4创建数据表5插入数据到数据库表下面我们将逐步解释每个步骤需要做什么,以及代码的实......
  • mysql完全卸载干净
    如何完全卸载MySQL介绍MySQL是一个常用的关系型数据库管理系统,但有时候我们需要完全卸载MySQL。本文将介绍一种可靠的方法来彻底移除MySQL。卸载过程概览以下是卸载MySQL的步骤概览。我们将使用命令行执行这些步骤。步骤操作1停止MySQL服务2卸载MySQL软件3......