基于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路径.…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
