面试官:MySQL也可以实现分布式锁吗?

首先说结论,可以做,但不推荐做。 我们并不推荐使用数据库实现分布式锁。

如果非要这么做,实现大概有两种。

1、锁住Java的方法,借助insert实现

如何用数据库实现分布式锁呢,简单来说就是创建一张锁表,比如:

CREATE TABLE `methodLock` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',`method_name` varchar(64) NOT NULL DEFAULT '' COMMENT '锁定的方法名',`desc` varchar(1024) NOT NULL DEFAULT '备注信息',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存数据时间,自动生成',PRIMARY KEY (`id`),UNIQUE KEY `uidx_method_name` (`method_name `) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='锁定中的方法';

当我们想锁住某个方法的时候,就往这张表插入一条数据,因为method_name建立了唯一索引,其他方法要执行的时候,就会因为插入失败而告终,最终保证只能是某一个服务的某一个线程成功执行该方法。执行完毕后,再delete这条数据就行了。

优点:容易理解,使用简单。

缺点:数据库有性能问题。

2、锁住某一行,借助for update实现

这个其实就是借助MySQL本身的行级锁排他锁来实现,但是要注意,where条件里面必须要走索引,防止退化为表级锁。

select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁,那么select......for update会锁表还是锁行?

验证:

创建表student,id是自增主键,给age 创建普通索引,phone创建唯一索引,字段name不加索引.

CREATE TABLE `student` (`id` int unsigned NOT NULL AUTO_INCREMENT,`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,`age` int NOT NULL,`phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `index_phone` (`phone`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

插入模拟数据:

INSERT INTO `student` (`id`, `name`, `age`, `phone`)
VALUES(1, '22222', 1, '111'),(2, '英语', 2, '1212'),(3, '22222', 3, '2121'),(4, '22222', 4, '21212'),(5, '1111111', 5, '4444');

用到的索引相关命令

#查询表student的所有索引
show index from student
#id是自增主键
#age 创建普通索引
CREATE INDEX idx_age ON student (`age`);
#phone创建唯一索引
CREATE UNIQUE INDEX index_phone ON student(phone);#name是普通字段
#age 创建普通索引,
#phone创建唯一索引

查看当前的索引情况:

需要关闭自动提交,通过set @@autocommit=0; 设置为手动提交。0代表手动提交,1代表自动提交。

实例1(主键): 会话1查询id=1的数据加了for update悲观锁,开启事务,并且没有提交。

会话2去更新id为1的数据,被阻塞了

会话1,提交事务(释放锁),会话2立刻就会查询到数据。

证明:根据主键进行 for update 查询时是行锁

实例2(普通索引age):

给普通索引age添加悲观锁,会话1查询age=5的记录,开启事务并不提交。在会话2中更新age=5,发现sql阻塞。

而在会话2中更新age=3的记录就不会阻塞。

证明:根据普通索引进行 for update 查询时是行锁 实例3:(唯一索引) 给唯一索引phone添加悲观锁,会话1查询phone=1212的记录,开启事务并不提交。在会话2中更新phone=1212的记录,发现sql阻塞。

而在会话2中更新phone=111的记录就不会阻塞。

证明:根据唯一索引进行 for update 查询时是行锁

实例4:普通字段name

给普通字段name 添加悲观锁,会话1查询name=‘英语’的记录,开启事务并不提交。在会话2中更新name=‘英语’的记录,发现sql阻塞。

会话2中更新name=‘22222’的记录,发现sql同样会阻塞。

证明:根据普通字段进行 for update 查询时是表锁

结论: 如果查询条件用了索引(普通索引,唯一索引)/主键,那么select ..... for update就会进行行锁。如果是普通字段,那么select ..... for update就会进行锁表。

实战

如何在java代码中使用悲观锁?

例如,小明和小红同时购买了同一件商品,系统会生成两个订单。在执行减少库存的操作之前,系统会对该商品的库存进行加锁。这意味着只有一个用户能够成功地执行减少库存的操作,而另一个用户必须等待第一个用户完成操作并释放锁后才能执行。 通过使用悲观锁,我们可以有效避免多个用户同时购买同一件商品导致的库存冲突问题。悲观锁确保了数据的一致性,但也带来了一些性能上的损耗,因为其他用户必须等待锁的释放才能继续操作。

实现方式:

@Select("select * from tb_goods where goods_id = #{goodsId} for update")
public TbGoods lock(String goodsId);

业务代码:

@Service
public class OrderService {@Autowiredprivate TbGoodsMapper goodsMapper;@Autowiredprivate TbOrderMapper orderMapper;@Transactionalpublic void buy(String goodsId){//获取数据库悲观锁(行锁)goodsMapper.lock(goodsId);//1:查询商品信息TbGoods tbGoods = goodsMapper.selectById(goodsId);if (tbGoods == null) {return;}//2:判断库存if(tbGoods.getGoodsStock1() <= 1){return;}//3:下单TbOrder tbOrder = new TbOrder();tbOrder.setOrderId(UUID.randomUUID().toString());tbOrder.setGoodsId(Integer.parseInt(goodsId));tbOrder.setOrderAmount(tbGoods.getGoodsPrice());orderMapper.insert(tbOrder);//4:修改库存tbGoods.setGoodsStock1(tbGoods.getGoodsStock1() - 1);goodsMapper.updateById(tbGoods);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/347351.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM 根可达算法

Java中的垃圾 Java中"垃圾"通常指的是不再被程序使用和引用的对象&#xff0c;具体表现在没有被栈、JNI指针和永久代对象所引用的对象。Java作为一种面向对象的编程语言&#xff0c;它使用自动内存管理机制&#xff0c;其中垃圾收集器负责检测和回收不再被程序引用的…

集成学习概述

概述 集成学习(Ensemble learning)就是将多个机器学习模型组合起来&#xff0c;共同工作以达到优化算法的目的。具体来讲&#xff0c;集成学习可以通过多个学习器相结合&#xff0c;来获得比单一学习器更优越的泛化性能。集成学习的一般步骤为&#xff1a;1.生产一组“个体学习…

开源WebGIS全流程常用技术栈

1 数据生产 1.1 uDig uDig&#xff08;http://udig.refractions.net/&#xff09;是一个基于Java开源的桌面应用框架&#xff0c;它构建在Eclipse RCP和GeoTools&#xff08;一个开源的Java GIS包)上。可以进行shp格式地图文件的编辑和查看&#xff1b;是一个开源空间数据查看…

excel两个数据表格,怎样实现筛选的联动?

如图&#xff0c;想要通过处理器或者像素条件进行筛选&#xff0c;形成一个右边图2的对比表&#xff0c;如何实现实现联动显示呢&#xff1f; 这个在excel里可以借用数据透视表切片器来完成。步骤如下&#xff1a; 1.添加表 选中数据区域中任意一个单元格&#xff0c;点击 插…

跳动圆点加载动画

效果图: 完整代码: <!DOCTYPE html> <html> <head><meta charset="UTF-8" /><title>跳动圆点加载动画</title><style type="text/css">body {background: #ECF0F1;display: flex;justify-content: center;al…

“改进型”Howland 电流泵电路

“改进型”Howland 电流泵电路 “改进型”Howland 电流泵是一种使用差分放大器在分流电阻器 (Rs) 上施加电压的电路&#xff0c;从而产生能够驱动大范 围负载电阻的双极性&#xff08;拉电流或灌电流&#xff09;压控电流源。 设计注释 确保运算放大器的输入端&#xff08;V…

串口调试助手软件(ATK-XCOM) 版本:v2.0

串口设置 软件启动后&#xff0c;会自动搜索可用的串口&#xff0c;可以显示详细的串口信息&#xff0c;由于兼容性原因某些电脑可能不会显示。 超高波特率接收&#xff0c;在硬件设别支持的情况下&#xff0c;可自定义波特率&#xff0c;点“自定义”即可输入您想要的波特率&…

pycharm爬取BOSS直聘岗位信息

编译器&#xff1a;Pycharm 效果展示如图 简单原理描述&#xff1a;模拟人工动作爬取页面信息&#xff0c;运行脚本后代码自动打开浏览器获取相关信息&#xff0c;模拟人工进行页面跳转并自动抓取页面信息记录到表格中。 深入原理描述&#xff1a;页面翻转的时候会调用接口&am…

用人工智能写2024年高考作文

目录 用人工智能写2024年高考作文 引用 一、2024年 新课标I卷 作文真题 AI写作范文 二、2024年 全国甲卷 作文真题 AI写作范文 三、2024年 新课标II卷 作文真题 AI写作范文 四、2024年 北京卷 作文真题一 AI写作范文 作文真题二 AI写作范文 作文真题三 AI写作…

MySQL是怎么保证持久性的(redo log日志相关)

Mysql中 事务的很多实现&#xff0c;都是因为有日志的支撑&#xff0c;比如binlog、undo log、redo log等 MySQL是怎么保证持久性的 持久性是指&#xff0c;事务一旦提交&#xff0c;它对数据库的改变就应该是永久性的&#xff0c;接下来的其他操作或故障不能对其有影响。In…

Linux/Windows 安装 RocketMQ 详细图文教程!

Linux 安装 RocketMQ 首先&#xff0c;你需要从RocketMQ的官方网站或GitHub仓库下载最新的RocketMQ发行版下载安装&#xff0c;官网下载地址&#xff1a;https://rocketmq.apache.org/download/。 接下来配置环境变量&#xff1a; 输入vim /etc/profile命令配置环境变量输入i进…

【动态规划】| 路径问题之不同路径 力扣62

&#x1f397;️ 主页&#xff1a;小夜时雨 &#x1f397;️ 专栏&#xff1a;动态规划 &#x1f397;️ 如何活着&#xff0c;是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/unique-paths/description/ 通常动态规划的题目有…

牛客little w and Discretization

玩一下样例发现&#xff0c;只要找到mex就可以知道有((1-mex)的值)所在的位置离散化后和原本的值是一样的&#xff0c;所以询问区间的长度-&#xff08;1-mex&#xff09;有几个值就是答案&#xff0c;数据范围3e5&#xff0c;莫队值域分块求区间mex,计算1-mex有几个位置属于这…

51单片机-实机演示(LED点阵)

目录 前言: 一.线位置 二.扩展 三.总结 前言: 这是一篇关于51单片机实机LED点阵的插线图和代码说明.另外还有一篇我写的仿真的连接在这:http://t.csdnimg.cn/ZNLCl,欢迎大家的点赞,评论,关注. 一.线位置 接线实机图. 引脚位置注意: 1. *-* P00->RE8 P01->RE7 …

孟德尔随机化R包:TwoSampleMR和MR-PRESSO安装

1. 孟德尔随机化R包 看一篇文章&#xff0c;介绍孟德尔随机化分析&#xff0c;里面推荐了这两个R包&#xff0c;安装了解一下&#xff1a; Methods:Genome-wide association study (GWAS) data for autoimmune diseases and AMD were obtained from the IEU Open GWAS databas…

C#客户端

控件 打开链接 Socket socket; // 打开连接 private void button1_Click(object sender, EventArgs e) {button1.Enabled false;button2.Enabled true;//1 创建socket客户端对象socket new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 2…

鸿蒙轻内核A核源码分析系列四(2) 虚拟内存

本文我们来熟悉下OpenHarmony鸿蒙轻内核提供的虚拟内存&#xff08;Virtual memory&#xff09;管理模块。 本文中所涉及的源码&#xff0c;以OpenHarmony LiteOS-A内核为例&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 获取。如果涉及开发板…

鸿蒙开发文件管理:【@ohos.environment (目录环境能力)】

目录环境能力 该模块提供环境目录能力&#xff0c;获取内存存储根目录、公共文件根目录的JS接口。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。本模块接口为系统接口&#xff0c;三方应用不支…

SLT简介【简单介绍SLT】

SLT简介 在c的学习当中STL的学习是一个很重要的一环&#xff0c;但是STL又是一个庞大的章节&#xff0c;因此这里我们先简单介绍一下STL&#xff0c;有助于后面我们对STL的学习&#xff0c;这里就是做一个简单的介绍&#xff0c;并无干货。 1.什么是STL STL(standard templa…

【Emacs Verilog mode保姆级的使用指南】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…