基于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 实现数据库分布式锁

注意事项

  1. select for update 必须在事务中才会生效。
  2. 该语法适用于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;}
}

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

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

相关文章

ES6 笔记02

目录 01 对象的扩展 02 链判断运算符 03 属性名表达式 04 Symbol 类型 05 set集合的使用 06 Map集合的使用 07 Set集合和Map集合的遍历方式 08 iterator迭代器 01 对象的扩展 对象的属性和方法的简洁表示: es6允许在字面量对象里面直接写变量名 let 变量名变量值; let …

金融业开源软件应用 评估规范

金融业开源软件应用 评估规范 1 范围 本文件规定了金融机构在应用开源软件时的评估要求&#xff0c;对开源软件的引入、维护和退出提出了实现 要求、评估方法和判定准则。 本文件适用于金融机构对应用的开源软件进行评估。 2 规范性引用文件 下列文件中的内容通过文中的规范…

WS2811 单线 256 级灰度三通道恒流 LED 驱动器芯片 IC

产品概述 WS2811 是三通道LED驱动控制专用电路&#xff0c;芯片内部包含了智能数字接口数据锁存信号整形放大驱动电路&#xff0c;还包含有高精度的内部振荡器和15V高压可编程定电流输出驱动器。同时&#xff0c;为了降低电源纹波&#xff0c;3个通道有一定的延时导通功…

【数据结构课程学习】:队列学习

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;数据结构课程学习 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f697; 1.队列的基本概念&#xff1a…

软考高级最容易被挂掉的论文,千万别乱写!

高级考生最没把握的科目应该就是论文了&#xff0c;有些考生考了几次都败在论文上了。那么导致论文不合格的写作误区有哪些&#xff1f;最后十多天&#xff0c;该如何准备呢&#xff1f; 常见写作误区 误区一&#xff1a;偏题 在论文写作时不能偏题&#xff0c;要紧扣子题干…

Visual Studio构建NodeJS原生代码在Electron中的报错问题

文章目录 对比NODE-GYP工具解决问题进一步研究win_delay_load_hook.cc代码MAC中是不需要这个东西的这个标题有点长,相对是一个比较具体的场景,但是这个问题在我自己的实际开发中,确实困扰了我一段时间。 因为在windows下做设备驱动,上位机的开发中。Visual Studio是一个比较…

要想通过等保测评,这7个问题你必须了解

1.什么是等级保护测评&#xff1f; 2.为什么要做等级保护测评&#xff1f; 3.等保1.0与2.0的区别在哪里&#xff1f; 4.等级保护测评参考标准有哪些&#xff1f; 5.等级保护测评的级别有哪些以及哪些系统需要&#xff1f; 6.等保测评的主要内容是什么&#xff1f; 7.等级…

如何利用代理IP高效采集全球热点,赋能短视频创作?

如何利用代理IP高效采集全球热点&#xff0c;赋能短视频创作&#xff1f; 一、摘要二、代理IP1. 什么是代理IP&#xff1f;2. 代理IP的分类3. 代理的重要性 三、如何选择可靠的代理IP服务商&#xff1f;四、IPIDEA代理IP简介1.IPIDEA简介2.IPIDEA的优势 五、获取代理IP1. 注册平…

python随机显示四级词汇

python实现一个浮动窗口随机显示四级单词在桌面跑来跑去 实现一个浮动窗体随机显示四级单词在windows桌面置顶移动 tkinter库来创建窗口和显示单词&#xff0c;以及random库来随机选择单词。 使用after方法来定时更新窗口的位置&#xff0c;实现单词窗口的慢慢移动效果 使用…

有机硅改性氟树脂性能进一步提升 市场需求增长空间大

有机硅改性氟树脂性能进一步提升 市场需求增长空间大 有机硅改性氟树脂&#xff0c;利用有机硅树脂对氟树脂进行改性得到一种新型的、性能更为优异的树脂材料。 有机硅树脂&#xff0c;具有柔韧性好、电绝缘、憎水、耐候、耐老化等优点&#xff0c;但固化温度高且时间长、附着力…

使用Apache Spark从MySQL到Kafka再到HDFS的数据转移

使用Apache Spark从MySQL到Kafka再到HDFS的数据转移 在本文中&#xff0c;将介绍如何构建一个实时数据pipeline&#xff0c;从MySQL数据库读取数据&#xff0c;通过Kafka传输数据&#xff0c;最终将数据存储到HDFS中。我们将使用Apache Spark的结构化流处理和流处理功能&#…

MySQL中表的插入,修改,删除语法

插入 插入数据有四种方法,代码如下 -- 给表中添加元素 -- insert into 表名 (列名) values(数据)INSERT INTO student(NAME,gender,birthday,phone)VALUES(张三,男,2003-2-10,13333333333) INSERT INTO student(NAME,gender,birthday,phone,address,height,rig_time) VALUES(…

在Mac环境下打包Python应用

1、创建虚拟环境 conda create -n ur_name python3.7 pip install -r requirement.txt 2、配置文件生成 cd ur_project py2applet --make-setup __main__.py 3、APP打包 # 编辑setup.py文件,具体参考本文文献 python setup.py py2app 用 py2app 将 Python 脚本打包成 Mac…

高级优化理论与方法(十二)

高级优化理论与方法&#xff08;十二&#xff09; LPDuality of LPWeek LP Duality TheoremStrong LP Duality TheoremCorollary Complementary Slackness ConditionRemarksExample Non-Simplex MethodsKhachiyan (Ellipsoid)Karmarkar (Interior point) Integer Linear Progra…

Leetcode-有效的括号

20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/valid-parentheses/ 题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&…

MongoDB 数据探索之道:查询文档操作详解

在 MongoDB 数据库中&#xff0c;查询文档是一种强大的工具&#xff0c;能够帮助您深入了解数据并提取所需信息。无论是从大型数据集中检索特定记录&#xff0c;还是进行数据统计和分析&#xff0c;查询文档都是不可或缺的。在本指南中&#xff0c;我们将深入探讨 MongoDB 查询…

c++ map,set封装

map 是一个 kv 结构&#xff0c; set 是 k结构。 我们前面模拟实现了 红黑树&#xff0c;但是我们实现的红黑树把 kv 结构写死了&#xff0c;怎么样才能用泛型编程的思想来实现map和set呢 我们先简单看一下原码中是怎么实现的 1.原码实现逻辑 我们打开这里的 stl_set.h 通过…

Dubbo基本使用

Dubbo基本使用 1.项目介绍2.开发步骤2.1 启动注册中心2.2 初始化项目2.3 添加 Maven 依赖2.3.1 父pom.xml2.3.1 consumer模块和provider模块pom.xml 2.4 定义服务接口2.5 定义服务端的实现2.6 配置服务端 Yaml 配置文件2.7 配置消费端 Yaml 配置文件2.8 基于 Spring 配置服务端…

芯片原厂工程师带你学 Linux 驱动

芯片原厂工程师&#xff0c;手把手带你学Linux驱动&#xff0c;感兴趣的点个关注私聊呀。 介绍&#xff1a; https://b2qtatgfkp.feishu.cn/docx/HoBKdezVFo6HlVx0hXPc8R7QnWc

Mysql sql_mode=only_full_group_by时如何实现根据单个字段分组

SELECT* FROMTABLE_NAME t group by device_id ORDER BY create_time desc报错 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column TABLE_NAME.t.id which is not functionally dependent on columns in GROUP BY clause; this is …