当前位置: 首页 > news >正文

高并发场景下解决并发数据不一致

简单的场景:
全量数据更新的情况下, 不在乎同一秒的请求都必须要成功, 只留下最新的更新请求数据

  • 方案常用的是
    1、数据库增加时间戳标识实现的乐观锁, 请求参数从源头带上微秒或者毫秒时间戳数据库存储, 然后在更新SQL语句上比较 (数据库的时间 < 参数传递的时间)
    例如:
    ALTER TABLE mytable ADD accessTime DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) not null comment ‘请求源头时间(精度高),用于更新比较,解决并发修改’;

UPDATE mytable SET updateTime = ?, accessTime=? WHERE
statusId = ?
AND
(IFNULL(accessTime, DATE_SUB(NOW(), INTERVAL 2 MINUTE)) < ?);
复杂场景:
比如, 更新数据时候不是全量数据更新的方式, 可能是增量更新或者是覆盖部分更新;
场景: 比如MongoDB数据库, 文档中的某个object字段下有很多key:value,
[图片]
一种并发情况: 并发A、B请求的时候, 他们的请求参数分别新增加不同的object字段下的Key, 或者是覆盖key, 这种新增Key的情况下需要并发的A、B请求都要成功,
{properties.label":24.700000}
{properties.thermostat.localTemp":24.800000}
另外一种情况: 并发A、B请求的时候, 他们的请求参数分别相同的object字段下的Key, 这种情况下需要并发的A、B请求只要最新请求能成功, 比如是A是先请求, B后请求, 那么就不能存在数据库最终存储的数据是A的;
{properties.thermostat.localTemp":24.700000}
{properties.thermostat.localTemp":24.800000}

  • 方案
    基于时间戳的乐观锁方式 + 判断keys的hash算法, 具体如下
    请求参数源码增加一个时间戳, 透传到数据库存储;
    根据请求测试里面的所有的keys , 按规则排序, 后进行hash算法计算出值, 然后插入到表里面;
    后面更新判断hash算法是否一致, 不一致则判断为增量更新, 不用判断时间戳让其更新成功;
    如果hash算法一致则判定为一致, 需要判断数据库时间戳 < 传递的时间戳;
    并且这个判断不能在程序中实现, 比如先查询出来然后再比较, 后更新, 这种方式不是原子性的;
    但是这种方法还是存在缺陷, 比如:
    A线程先请求 参数是: b=2 {“fanMode”: “auto1”, “speedPercent”: 0} A 由于hash不同也能更新成功, 最终b=2, 但是由于是B后请求是, 其实最终数据要b=1
    B线程后请求 参数是: b=1 {“fanMode”: “auto2”} B先执行成功;
    上面方法主要是解决相邻的2个间隔短的相同key参数请求
  • 伪代码:
    // 并发控制, 组装请求参数的TreeSet排序的keys-1
    Set propertiesKeys = new TreeSet<>();
    for (Map.Entry<String, Object> entry : properties.entrySet()) {
    if (entry.getValue() == null) {
    continue;
    }
    // 并发控制, 组装请求参数的keys-2
    propertiesKeys.add(entry.getKey());
    recursiveCalculationAddKeys(entry.getValue(), propertiesKeys);
    }
    // 并发控制, 获取keys_Md5-3
    String string = propertiesKeys.toString();
    String md5DigestAsHex = DigestUtils.md5DigestAsHex(string.getBytes(StandardCharsets.UTF_8));
    deviceStatus.setPropertiesKeysMd5(md5DigestAsHex);
    request.setCompareAccessTime(Boolean.TRUE);

public static void recursiveCalculationAddKeys(Object value, Set propertiesKeys) {
if (Objects.isNull(value)){
return;
}
String type = value.getClass().getSimpleName();
if (value instanceof Map || type.endsWith(“HashMap”)) {
Map<String, Object> valueMap = (Map<String, Object>) value;
valueMap.forEach((k, v) -> {
propertiesKeys.add(k);
// 递归处理所有是map的值
recursiveCalculationAddKeys(v, propertiesKeys);
});
}

// 处理是List的情况
if (value instanceof List || type.endsWith("ArrayList")){List<Object> valueList = (List<Object>) value;valueList.forEach(el->{// 递归处理所有是map的值recursiveCalculationAddKeys(el, propertiesKeys);});
}

}


Criteria criteriaVar2 = Criteria.where(“statusId”).is(oldDs.getStatusId());
Query queryVar2 = new Query(criteriaVar2);

if (compareAccessTime) {
// md5比较存在情况下增加查询条件&走单更新方法
criteriaVar2.orOperator(
Criteria.where(“propertiesKeysMd5”).is(propertiesKeysMd5).and(“accessTime”).lt(accessTime),
Criteria.where(“accessTime”).is(null),
Criteria.where(“propertiesKeysMd5”).is(null),
Criteria.where(“propertiesKeysMd5”).ne(propertiesKeysMd5)
); // 匹配空值
queryVar2 = new Query(criteriaVar2);
}


mongoTemplate.findAndModify(queryVar2, update, Map.class, “…”)

1

相关文章:

高并发场景下解决并发数据不一致

简单的场景: 全量数据更新的情况下, 不在乎同一秒的请求都必须要成功, 只留下最新的更新请求数据 方案常用的是 1、数据库增加时间戳标识实现的乐观锁, 请求参数从源头带上微秒或者毫秒时间戳数据库存储, 然后在更新SQL语句上比较 (数据库的时间 < 参数传递的时间) 例如: A…...

OpenAI GPT-o1实现方案记录与梳理

本篇文章用于记录从各处收集到的o1复现方案的推测以及介绍 目录 Journey Learning - 上海交通大学NYUMBZUAIGAIRCore IdeaKey QuestionsKey TechnologiesTrainingInference A Tutorial on LLM Reasoning: Relevant methods behind ChatGPT o1 - UCL汪军教授Core Idea先导自回归…...

Excel:vba实现生成随机数

Sub 生成随机数字()Dim randomNumber As IntegerDim minValue As IntegerDim maxValue As Integer 设置随机数的范围(假入班级里面有43个学生&#xff0c;学号是从1→43)minValue 1maxValue 43 生成随机数(在1到43之间生成随机数)randomNumber Application.WorksheetFunctio…...

Python | Leetcode Python题解之第506题相对名次

题目&#xff1a; 题解&#xff1a; class Solution:desc ("Gold Medal", "Silver Medal", "Bronze Medal")def findRelativeRanks(self, score: List[int]) -> List[str]:ans [""] * len(score)arr sorted(enumerate(score), …...

安全见闻(6)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;安全见闻&#xff08;6&#xff09;_哔哩哔哩_bilibili 学无止境&#xff0c;开拓自己的眼界才能走的更远 本文主要讲解通讯协议涉及的安全问题。…...

Promise、async、await 、异步生成器的错误处理方案

1、Promise.all 的错误处理 Promise.all 方法接受一个 Promise 数组&#xff0c;并返回所有解析 Promise 的结果数组&#xff1a; const promise1 Promise.resolve("one"); const promise2 Promise.resolve("two");Promise.all([promise1, promise2]).…...

腾讯云:数智教育专场-学习笔记

15点13分2024年10月21日&#xff08;短短5天的时间&#xff0c;自己的成长速度更加惊人&#xff09;-开始进行“降本增效”学习模式&#xff0c;根据小米手环对于自己的行为模式分析&#xff08;不断地寻找数据之间的关联性&#xff09;&#xff0c;每天高效记忆时间&#xff0…...

Ovis: 多模态大语言模型的结构化嵌入对齐

论文题目&#xff1a;Ovis: Structural Embedding Alignment for Multimodal Large Language Model 论文地址&#xff1a;https://arxiv.org/pdf/2405.20797 github地址&#xff1a;https://github.com/AIDC-AI/Ovis/?tabreadme-ov-file 今天&#xff0c;我将分享一项重要的研…...

python的Django的render_to_string函数和render函数模板的使用

一、render_to_string render_to_string 是 Django 框架中的一个便捷函数&#xff0c;用于将模板渲染为字符串。 render_to_string(template_name.html, context, requestNone, usingNone) template_name.html&#xff1a;要渲染的模板文件的名称。context&#xff1a;传递给…...

基于Python大数据的王者荣耀战队数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

【Linux学习】(3)Linux的基本指令操作

前言 配置Xshell登录远程服务器Linux的基本指令——man、cp、mv、alias&which、cat&more&less、head&tail、date、cal、find、grep、zip&tar、bc、unameLinux常用热键 一、配置Xshell登录远程服务器 以前我们登录使用指令&#xff1a; ssh 用户名你的公网…...

Mac 使用脚本批量导入 Apple 歌曲

最近呢&#xff0c;买了一个 iPad&#xff0c;虽然家里笔记本台式都有&#xff0c;显示器都是 2个&#xff0c;比较方便看代码&#xff08;边打游戏边追剧&#xff09;。 但是在床上拿笔记本始终还是不方便&#xff0c;手机在家看还是小了点&#xff0c;自从有 iPad 之后&…...

全桥PFC电路及MATLAB仿真

一、PFC电路原理概述 PFC全称“Power Factor Correction”&#xff08;功率因数校正&#xff09;&#xff0c;PFC电路即能对功率因数进行校正&#xff0c;或者说是能提高功率因数的电路。是开关电源中很常见的电路。功率因数是用来描述电力系统中有功功率&#xff08;实际使用…...

【安当产品应用案例100集】025-确保数据安全传输——基于KMS与HSM的定期分发加密解决方案

引言&#xff1a; 在当今快速发展的数字化时代&#xff0c;企业面临着前所未有的信息安全挑战。尤其是在需要向供应商定期分发敏感数据的情况下&#xff0c;如何保证这些数据在传输过程中的安全性变得至关重要。为此&#xff0c;我们推出了结合安当KMS密钥管理平台与HSM密码机…...

十 缺陷检测解决策略之三:频域+空域

十 缺陷检测解决策略之三:频域空域 read_image (Image, 矩形) * 中间低频&#xff0c;四周高频 fft_image (Image, ImageFFT) * 中间低频&#xff0c;四周高频 fft_generic (Image, ImageFFT1, to_freq, -1, sqrt, dc_center, complex) * 中间高频&#xff0c;四周低频 rft_ge…...

有望第一次走出慢牛

A股已走完30多年历程。 大约每十年&#xff0c;会经历一轮牛熊周期。特点是每一轮周期&#xff0c;大约九成的时间都是熊市主导。就是我们常说的 快牛慢熊。 这一次&#xff0c;会不会重复历史? 历史不会简单重复。已经感受到了盘面的变化。 有人说&#xff0c;股市爆涨爆…...

计算机网络(十二) —— 高级IO

#1024程序员节 | 征文# 目录 一&#xff0c;预备 1.1 重新理解IO 1.2 五种IO模型 1.3 非阻塞IO 二&#xff0c;select 2.1 关于select 2.2 select接口参数解释 2.3 timeval结构体和fd_set类型 2.4 socket就绪条件 2.5 select基本工作流程 2.6 简单select的服务器代…...

电力行业 | 等保测评(网络安全等级保护)工作全解

电力行业为什么要做网络安全等级保护&#xff1f; 电力行业是关系到国家安全和社会稳定的基础性行业&#xff0c;电力行业信息化程度相对较高&#xff0c;是首批国家信息安全等级保护的重点行业。 01 国家法律法规的要求 1994《计算机信息系统安全保护条例》&#xff08;国务…...

总裁主题CeoMax-Pro主题7.6开心版

激活方式&#xff1a; 1.授权接口源码ceotheme-auth-api.zip搭建一个站点&#xff0c;绑定www.ceotheme.com域名&#xff0c;并配置任意一个域名的 SSL 证书。 2.在 hosts 中添加&#xff1a;127.0.0.1 www.ceotheme.com 3.上传class-wp-http.php到wp-includes目录&#xff…...

深入探讨编程的核心概念、学习路径、实际应用以及对未来的影响

在当今这个数字化时代&#xff0c;编程已成为连接现实与虚拟世界的桥梁&#xff0c;它不仅塑造了我们的生活方式&#xff0c;还推动了科技的飞速发展。从简单的网页制作到复杂的人工智能系统&#xff0c;编程无处不在&#xff0c;其重要性不言而喻。本文旨在深入探讨编程的核心…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

Windows 下端口占用排查与释放全攻略

Windows 下端口占用排查与释放全攻略​ 在开发和运维过程中&#xff0c;经常会遇到端口被占用的问题&#xff08;如 8080、3306 等常用端口&#xff09;。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口&#xff0c;帮助你高效解决此类问题。​ 一、准…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目

应用场景&#xff1a; 1、常规某个机器被钓鱼后门攻击后&#xff0c;我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后&#xff0c;我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...