基于select for update 实现数据库分布式锁
1、select for update 的基本语法
SELECT * FROM table_name WHERE condition FOR UPDATE;
2、select for update 的定义及作用
2.1 、select for update的含义是在查询数据的同时对所选的数据行进行锁定,以保证数据的一致性和并发控制。在并发环境下,多个事务可能同时对同一数据进行读取和修改。如果不加任何锁机制,就会出现脏数据的情况,即一个事务读取了另一个事务尚未提交的数据,导致数据不一致。
2.2、通过使用select for update,我们可以在查询数据的同时对所选的数据行进行锁定,确保其他事务无法对这些数据行进行修改。这种加锁机制可以有效地避免脏数据的问题,保证数据的一致性。
3、基于select for update 实现数据库分布式锁
注意事项
- select for update 必须在事务中才会生效。
- 该语法适用于mysql的innodb 数据库引擎。
java实现
package com.monika.main.system.lock.impl;import com.monika.main.system.lock.Lock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.beans.factory.InitializingBean;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;/*** @author:whh* @date: 2024-05-11 18:47* <p></p>*/@Component
public class JdbcRowLock implements Lock,InitializingBean {private static final Logger LOG = LoggerFactory.getLogger(JdbcRowLock.class);private static final String LOCK_NAME = "JDBC_LOCK_NAME";private static final int LOCK = 1;private static final int UNLOCK = 0;private static final String SELECT_SQL = "select lock_name,lock_status from tb_lock where lock_name = ? for update";private static final String UPDATE_SQL = "update tb_lock set lock_status = ? where lock_name = ?";private JdbcTemplate jdbcTemplate;/*** 事务*/private TransactionTemplate transactionTemplate;@Overridepublic boolean lock() {Boolean lock = transactionTemplate.execute(action -> {Map<String, Object> result = jdbcTemplate.queryForMap(SELECT_SQL, LOCK_NAME);int lockStatus = (int) result.get("lock_status");if (LOCK == lockStatus) {LOG.info("线程{}获取锁[{}]失败,当前锁已被占用", Thread.currentThread().getName(), LOCK_NAME);return false;}jdbcTemplate.update(UPDATE_SQL, ps -> {ps.setInt(1, LOCK);ps.setString(2, LOCK_NAME);});LOG.info("线程{}获取锁[{}]成功", Thread.currentThread().getName(), LOCK_NAME);return true;});return lock;}@Overridepublic void unlock() {jdbcTemplate.update(UPDATE_SQL, ps -> {ps.setInt(1, UNLOCK);ps.setString(2, LOCK_NAME);});LOG.info("线程{}释放锁[{}]成功", Thread.currentThread().getName(), LOCK_NAME);}@Overridepublic void interrupt() {jdbcTemplate.update(UPDATE_SQL, ps -> {ps.setInt(1, UNLOCK);ps.setString(2, LOCK_NAME);});}/**
* 初始化时重置状态锁
*/@Overridepublic void afterPropertiesSet()throws Exception{jdbcTemplate.update(UPDATE_SQL, ps -> {ps.setInt(1, UNLOCK);ps.setString(2, LOCK_NAME);});}@Autowiredpublic JdbcRowLock(JdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) {this.jdbcTemplate = jdbcTemplate;this.transactionTemplate = transactionTemplate;}
}相关文章:
基于select for update 实现数据库分布式锁
1、select for update 的基本语法 SELECT * FROM table_name WHERE condition FOR UPDATE;2、select for update 的定义及作用 2.1 、select for update的含义是在查询数据的同时对所选的数据行进行锁定,以保证数据的一致性和并发控制。在并发环境下,多…...
Java后端实现对象与文件接收数据(minio测试)
实现思路: 1. 两个接口实现,一个接对象数据(file),一个接文件数据(json)。 2. json对象(base64String) 实体类信息 ,请求体统一接收 3. file, String name ,String password ,String name , Controller层接收 统一…...
考研踩坑经验分享
文章目录 写在前面自身情况简介自身学习路线优点坑点 学习路线建议1、2和3月份3、4和5月份6、7和8月份9、10月份11、12月份 一些私货建议结尾 写在前面 考研是一件非常有盼头的事,但绝对不是一件容易的事。 如果你不能做好来年三月份出成绩时,坦然接受…...
Android Compose 一:基础控件
Flutter 与 Compose 组件辣么像,难道是同一个google团队整的;也未深究,只是猜测。 创建项目 需要使用新版本Android studio,忽略步骤… 项目目录 MainActivity说明 1 系统默认页面 Preview 修饰的方法,只用来供开发…...
python3.12.0 在Linux 制作镜像包 部署到docker 全过程
项目结构: 比如,在pycharm里需要运行 themain.py 1、上传Linux的目录结构: Dockerfile 文件需要制作: 这里是关键: #基于的基础镜像 FROM python:3.12.0 #代码添加到code文件夹 ADD ./EF_NFCS /code #设置code文…...
STM32理论 —— μCOS-Ⅲ(新)
文章目录 1. 任务调度器1.1 抢占式调度 μCos-Ⅲ全称是Micro C OS Ⅲ,由Micriμm 公司发布的一个基于C 语言编写的第三代小型实时操作系统(RTOS); RTOS 与裸机相比最大的优势在于多任务管理与实时性,它提供了多任务管理和任务间通信的功能&a…...
衢州知识付费系统报价,教师如何做精品课程?怎么创造精品课程?
精品课程对于学生的意义来说是不同的,越是精品让学习的人就越觉得值得,所以,做为教师来说,做出精品课程不仅仅是对学生负责,也是对自己负责,那如何做精品课程?相信很多教师们也想知道。 如何创造精品课程?…...
在Vue中,可以通过使用<slot>元素和name属性来创建具名插槽。这样您就可以为一个组件的不同部分定义不同的内容。 以下是一个简单的示例:
在Vue中,可以通过使用元素和name属性来创建具名插槽。这样您就可以为一个组件的不同部分定义不同的内容。 以下是一个简单的示例: <template><div><header><slot name"header"></slot></header><mai…...
C++笔试强训day19
目录 1.小易的升级之路 2.礼物的最大价值 3.对称之美 1.小易的升级之路 链接 模拟就行,唯一可能是难点得就是gcd(最大公约数) #include <iostream> using namespace std; #define int long long const int N 1e5 10; int arr[N];…...
MySQL软件安装基于压缩包
打开mysql官网网址 MySQL :: Download MySQL Community Server 本次针对版本8的安装包方式进行安装,下载成功后接下来对MySQL进行安装 下载后有一个以zip后缀结尾的压缩包文件 对于安装包方式安装,比起可视化安装省去了许多安装步骤,这里直接…...
04 贝尔曼最优公式
贝尔曼最优公式 前言1、Motivating examples2、Definition of optimal policy3、Bellman optimality equation(BOE):Introduction4、 BOE:Maximization on the right-hand side5、BOE:Rewrite as v f(v)6、Contraction mapping theorem7、BO…...
印象笔记使用技巧
印象笔记(Evernote)是一款广泛使用的笔记应用,它帮助用户整理个人信息、文件和备忘录。以下是一些提高在印象笔记中效率的使用技巧: ### 1. 使用标签和笔记本组织笔记 - **建立笔记本**:为不同的项目或类别创建笔记本…...
产品设计中的“注册”说明
在使用网站或应用的时候必不可少的就是账号系统,账号系统有些人可能觉得简单,无非就是账号密码。真的是这样吗? 一个完整的账号系统通常大家会分成四部分: 1.注册(手机号、邮箱、用户名/密码限制/验证码)…...
【linux学习】多线程(1)
文章目录 线程的概念线程与进程 线程的用法线程的创建多线程 线程的等待线程锁死锁 线程的概念 在Linux中,线程(Thread)是程序执行流的最小单位,是进程中的一个实体,负责在程序中执行代码。线程本身不拥有系统资源&…...
Leetcode 3149. Find the Minimum Cost Array Permutation
Leetcode 3149. Find the Minimum Cost Array Permutation 1. 解题思路2. 代码实现 题目链接:3149. Find the Minimum Cost Array Permutation 1. 解题思路 这一题的话就是一个动态规划的问题,不过他这个错位着实是把题目变得复杂了不少,唉…...
Python | 为列表中的元素分配唯一值
我们可以给列表中的所有数字分配一个唯一的值,重复时它会保留给它的值。这是一个非常常见的问题,在Web开发中,处理物品id时会遇到。让我们讨论一下解决这个问题的一些方法。 1. 使用enumerate() 列表解析 # initializing list test_list …...
HTML炫酷的相册
目录 写在前面 HTML简介 完整代码 代码分析 系列推荐 写在最后 写在前面 本期小编给大家带来一个炫酷的旋转相册,快来解锁属于你的独家记忆吧! HTML简介 HTML(全称为超文本标记语言)是一种用于创建网页结构和内容的标记语…...
C++笔试强训day20
目录 1.经此一役小红所向无敌 2.连续子数组最大和 3.非对称之美 1.经此一役小红所向无敌 链接 简单模拟即可。 需要注意的是: 除完之后有无余数,若有,则还可以再挨一次打。 #include <iostream> using namespace std; #define in…...
【PHP【实战项目】系统性教学】——使用最精简的代码完成用户的登录与退出
👨💻个人主页:开发者-曼亿点 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 曼亿点 原创 👨💻 收录于专栏:…...
Linux下的常用基本指令
基本指令 前言一、ls 指令语法功能常用选项举例注意要点关于拼接关于 -a关于文件ls与/的联用ls与根目录ls与任意文件夹ls与常用选项与路径 ls -d与ls -ldls与ll 二、pwd命令语法功能常用选项注意要点window与Linux文件路径的区别家目录 三、cd 指令语法功能举例注意要点cd路径.…...
ECharts 5.4.3实战:3步打造科技感爆棚的流光折线图(附完整代码)
ECharts 5.4.3实战:3步打造科技感爆棚的流光折线图(附完整代码) 在数据可视化领域,ECharts凭借其强大的功能和灵活的配置选项,已经成为前端开发者的首选工具之一。特别是其丰富的动画效果,能够为静态数据注…...
从零开始!DeepSeek-R1-Distill-Qwen-1.5B完整部署流程详解
从零开始!DeepSeek-R1-Distill-Qwen-1.5B完整部署流程详解 1. 模型简介与核心优势 1.1 什么是DeepSeek-R1-Distill-Qwen-1.5B? DeepSeek-R1-Distill-Qwen-1.5B是一款经过知识蒸馏优化的轻量级语言模型,由DeepSeek团队基于Qwen-1.5B架构开发…...
专业数据恢复工具对决:UFS Explorer与R-Studio的实战选型指南
1. 数据恢复工具的核心价值与选型逻辑 当硬盘突然罢工或重要文件被误删时,专业数据恢复软件就像数字世界的急救医生。我经历过太多凌晨三点被叫醒处理服务器崩溃的案例,选对工具往往能决定数据"复活"的成功率。UFS Explorer和R-Studio这对老对…...
Maven Versions Plugin 使用指南
以下是对你提供内容的补充和整理,形成一篇关于 Maven Versions Plugin 使用指南的文章:Maven Versions Plugin 使用指南 Maven Versions Plugin 是一套用于管理项目版本、依赖版本和父版本的工具集合。它可以帮助你高效地更新项目版本号、检查依赖更新、…...
Windows右键菜单重构指南:从混乱到高效的ContextMenuManager实战
Windows右键菜单重构指南:从混乱到高效的ContextMenuManager实战 【免费下载链接】ContextMenuManager 🖱️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 问题诊断:你的右键菜单是…...
AIVideo一站式AI长视频工具与Visual Studio的深度集成开发
AIVideo一站式AI长视频工具与Visual Studio的深度集成开发 1. 引言 作为一名长期使用Visual Studio进行开发的程序员,我经常遇到这样的痛点:想要录制一段代码演示视频,需要反复切换多个软件;想要制作项目介绍视频,得…...
手把手教你部署M2FP:快速搭建人体部位识别服务
手把手教你部署M2FP:快速搭建人体部位识别服务 1. 引言:为什么选择M2FP进行人体解析? 在计算机视觉领域,人体解析(Human Parsing)是一项关键技术,它能够将图像中的人体划分为多个语义区域&…...
BAGEL终极指南:解密多模态AI模型的三大核心组件协同机制
BAGEL终极指南:解密多模态AI模型的三大核心组件协同机制 【免费下载链接】Bagel BAGEL是一个开源的多模态基础模型,拥有70亿个活跃参数(总共140亿个),在大规模交错的多模态数据上进行了训练。BAGEL在标准的多模态理解排…...
nfc-list使用教程
nfc-list 是 Kali Linux 中基于 libnfc 库(开源 NFC 开发框架)的基础 NFC/RFID 设备检测工具,核心功能是扫描并列出当前连接的 NFC 读卡器设备,以及贴近读卡器的 NFC 卡片(或标签)的详细信息,包…...
STM32环境监测系统在烟花爆竹仓库的应用
1. 项目概述与背景烟花爆竹作为一种特殊商品,其存储环境的安全管理一直是行业痛点。传统的人工巡检方式存在明显的滞后性——我曾亲眼见过一家小型烟花仓库因为夜间温湿度骤变而引发自燃,等值班人员发现时火势已难以控制。这个基于STM32的环境监测系统正…...
