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

黑马店评-04缓存更新策略,保证MySQL数据库中的数据和Redis中缓存的数据一致性

缓存更新策略(数据一致)

更新策略

缓存更新是Redis为了节约内存而设计出来的机制,当我们向Redis插入太多数据时就会导致缓存中的数据过多,所以Redis会对部分数据进行更新即淘汰

  • 低一致性需求(数据长久不发生变化): 使用内存淘汰机制,例如店铺类型信息的查询缓存,因为这部分数据很长一段时间都不需要更新
  • 高一致性需求: 使用主动更新机制,写入缓存的时候需要设置超时时间,例如店铺详情查询的缓存

在这里插入图片描述

主动更新实现

主动更新策略一般有如下几种方案

在这里插入图片描述

人工编码的三大问题

更新数据库后,删除缓存还是更新缓存?

  • 更新缓存: 每次更新数据库都更新缓存,如果中间没有人执行查询操作(写多读少),那么这些对缓存的更新动做就是无效的(用户根本就不会去缓存中查询数据)
  • 删除缓存: 更新数据库时把缓存删掉,只有用户下次做查询操作时才会更新缓存(用户发现Redis中没有数据就会去查询数据库同时把查询到的数据写入缓存)

如何保证缓存与数据库的操作的同时成功或失败?

  • 在单体系统中将缓存与数据库操作放在一个事务
  • 在分布式系统中利用TCC等分布式事务方案

先操作缓存还是先操作数据库?

  • 虽然这二者都存在线程安全问题,但是由于删除缓存的操作很快,更新数据库的操作相对较慢, 所以先操作数据库再删除缓存出现线程安全问题的概率相对较低

在这里插入图片描述

实现商铺缓存与数据库一致

根据店铺Id查询店铺时如果缓存未命中则查询数据库,将查询到的店铺信息写入Redis的同时设置缓存的超时时间

public static final Long CACHE_SHOP_TTL = 30L;
@Override
public Result queryById(Long id) {// 先从Redis中查询对应的店铺缓存,这里的常量值是固定的前缀+店铺idString shopJson = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY + id);// 如果在Redis中查询到了店铺信息(String类型的JSON字符串)则转为Shop类型直接返回if (StrUtil.isNotBlank(shopJson)) {Shop shop = JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}// 在Redis中没查询到对应的店铺缓存信息则根据店铺Id去数据库中查询店铺信息Shop shop = getById(id);// 在数据库中也查不到就返回一个错误信息或者返回空(根据业务需求)if (shop == null){return Result.fail("店铺不存在!!");}// 在数据库中查到了店铺信息,则将shop对象转为json字符串存入redis同时设置缓存的超时时间(如30分钟)String jsonStr = JSONUtil.toJsonStr(shop);stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, jsonStr,CACHE_SHOP_TTL, TimeUnit.MINUTES);// 最终把查询到的店铺信息返回给前端return Result.ok(shop);
}

根据店铺Id修改店铺时先修改数据库再删除缓存来解决双写问题,更新和删除通过事务去控制, 业务逻辑我们依旧是写在Service层的实现类中

// 更新商铺信息
@PutMapping
public Result updateShop(@RequestBody Shop shop) {// 直接将请求体中JSON格式的店铺信息写入数据库,这样在缓存有效期内,即使数据库中的店铺信息修改了,下次获取的还是之前缓存中的店铺信息shopService.updateById(shop);return Result.ok();
}
// 更新商铺信息
@PutMapping
public Result updateShop(@RequestBody Shop shop) {// 先将请求体中JSON格式的店铺信息写入数据库,再删除缓存,保证缓存中的店铺信息和数据库中的店铺信息一致性return shopService.update(shop);
}public interface IShopService extends IService<Shop> {Result update(Shop shop);}@Override
@Transactional
public Result update(Shop shop) {// 首先先判一下店铺Id是否为空if (shop.getId() == null){return Result.fail("店铺id不能为空!!");}// 先修改数据库中对应的店铺信息updateById(shop);// 再将Redis中对应店铺的缓存删除stringRedisTemplate.delete(CACHE_SHOP_KEY + shop.getId());return Result.ok();
}

重启服务器进行测试,如访问餐厅时会将该餐厅的数据缓存到Redis中,然后使用POSTMAN携带JSON数据发送PUT请求http://localhost:8080/api/shop/更新餐厅信息

  • 店铺的信息修改后就不会再出现在Redis缓存中了, 只有我们再次访问时才会去数据库中查询店铺信息并写入缓存
{"area": "大关","openHours": "10:00-22:00","sold": 4215,"address": "金华路锦昌文华苑29号","comments": 3035,"avgPrice": 80,"score": 37,"name": "yunqing茶餐厅","typeId": 1,"id": 1
}

相关文章:

黑马店评-04缓存更新策略,保证MySQL数据库中的数据和Redis中缓存的数据一致性

缓存更新策略(数据一致) 更新策略 缓存更新是Redis为了节约内存而设计出来的机制,当我们向Redis插入太多数据时就会导致缓存中的数据过多,所以Redis会对部分数据进行更新即淘汰 低一致性需求(数据长久不发生变化): 使用内存淘汰机制,例如店铺类型信息的查询缓存,因为这部分…...

matlab相机标定实验

实验原理 1. 相机标定坐标系 相机的参数对目标的识别、定位精度有很大的影响&#xff0c;相机标定就是为了求出相机的内外参数。标定中有3个不同层次的坐标系&#xff1a;世界坐标系、相机坐标系和图像坐标系&#xff08;图像物理坐标系和图像像素坐标系&#xff09;。世界坐…...

【每日一题Day343】LC2731移动机器人 | 脑筋急转弯+数学

移动机器人【LC2731】 有一些机器人分布在一条无限长的数轴上&#xff0c;他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时&#xff0c;它们以每秒钟一单位的速度开始移动。 给你一个字符串 s &#xff0c;每个字符按顺序分别表示每个机器人移动…...

疯狂java 1.7垃圾回收机制

内存泄漏&#xff1a;如果一些分配出去的内存得不到及时回收&#xff0c;就会引起系统运行速度下降&#xff0c;甚至导致程序瘫痪 Java程序的内存分配和回收都是由JRE在后台自动进行的。JRE会负责回收哪些不再使用的内存&#xff0c;这种机制被称为垃圾回收&#xff08;Garbag…...

day01_基础

零、今日内容 1 jdk 2 idea使用 3 HelloWorld程序 4 变量 5 数据类型 6 String 一、JDK安装 JDK java开发工具包,敲代码的环境 1.1 卸载 控制面板 -> 卸载程序 -> 选择jdk,右键卸载 1.2 安装 注意: 现在安装的是JDK8版本,虽然最新的版本是21版本,但是工作市场中最流行的…...

RabbitMQ开启消息发送确认和消费手动确认

开启RabbitMQ的生产者发送消息到RabbitMQ服务端的接收确认&#xff08;ACK&#xff09;和消费者通过手动确认或者丢弃消费的消息。 通过配置 publisher-confirm-type: correlated 和publisher-returns: true开启生产者确认消息。 server:port: 8014spring:rabbitmq:username: …...

嵌入式系统开发【深入浅出】 GPIO 类设备的驱动程序

目录 GPIO管脚的输出功能相当于控制、输入相当于检测 使用GPIO基本流程 对于某一个管脚来说最多有几种功能&#xff1f; 拓展 【定时器与系统定时器】 决定定时长短的因素: 普通定时器 系统定时器 STM32F103RBT6的时钟源有哪五种 sysclk 的时钟频率由哪个时钟源提供基…...

项目管理必备的22个公式

大家好&#xff0c;我是老原。 趁着国庆时间比较空闲&#xff0c;给你们整理了一些项目管理必备的计算公式&#xff0c;一共22个。 每一个公式都给你们标注了适用情况和使用方法&#xff0c;为了方便你们理解&#xff0c;也加了一些例子&#xff0c;保准你看了就会。 觉得不…...

ccache加速编译速度

ccache https://gitee.com/lixiaoxmm/ccache.git 依赖hiredis、zstd(zstd的cmakelists.txt在build/cmake目录下) 下载mingw,https://www.mingw-w64.org/downloads/#w64devkit hiredis、zstd使用mingw编译 cmake -G “MinGW Makefiles” cmakecache.txt手动修改去掉网络下载,…...

Apache POI使用

1.导入坐标 <!-- poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>${poi}</version></dependency><dependency><groupId>org.apache.poi</groupId><a…...

UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)

A - Weak Beats 链接 : A - Weak Beats 思路 : 模拟即可,如果在偶数位上出现了非0得元素&#xff0c;直接输出"No"后返回即可&#xff0c;循环顺利结束的话&#xff0c;就直接输出"Yes"; 代码 : #include<bits/stdc.h> #define IOS ios::sy…...

Docker 网络管理

Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认网关。因为在同一宿主机…...

网络安全国家队-安防思考与实践

按照工信部“三同步”安全建设的统一要求&#xff0c;本项目的实施应具备符合等级保护要求的安全防护措施&#xff08;主要为传输控制、防火墙隔离、入侵检测、安全审计等网络安全措施&#xff1b;操作系统安全、数据库安全、防病毒管理、安全审计等基础系统安全措施&#xff0…...

epoll 定时器

参考&#xff1a; Linux下使用epoll监听定时器-CSDN博客 但是这个用的是gettimeofday。 本人使用的是 #include <stdlib.h> #include<stdio.h> #include <sys/timerfd.h> #include <sys/epoll.h> #include <unistd.h> #include <sys/time.…...

BUUCTF Java逆向解密 1

Class文件是Java编译后的二进制字节码文件。 我这里使用的是jadx-gui&#xff0c;直接将class文件拖进去即可 package defpackage;import java.util.ArrayList; import java.util.Scanner;/* renamed from: Reverse reason: default package */ /* loaded from: Reverse.clas…...

BUUCTF [MRCTF2020]Ez_bypass1

这道题全程我都是用bp做的 拿到题目 我们查看页面源代码得到 代码审计 我们要用get传入id和gg两个参数&#xff0c;id和gg的值要求不能相等&#xff0c;但是id和gg的md5强比较必须相等 if(isset($_GET[gg])&&isset($_GET[id])) {$id$_GET[id];$gg$_GET[gg];if (md5($…...

深入理解强化学习——强化学习和有监督学习

分类目录&#xff1a;《深入理解强化学习》总目录 通过前文的介绍&#xff0c;我们现在应该已经对强化学习的基本数学概念有了一定的了解。这里我们回过头来再看看一般的有监督学习和强化学习的区别。以图片分类为例&#xff0c;有监督学习&#xff08;Supervised Learning&…...

设计模式 - 结构型模式考点篇:装饰者模式(概念 | 案例实现 | 优缺点 | 使用场景)

目录 一、结构型模式 1.1、装饰者模式 1.1.1、概念 1.1.2、案例实现 1.1.3、优缺点 1.1.4、使用场景 一、结构型模式 1.1、装饰者模式 1.1.1、概念 装饰者模式就是指在不改变现有对象结构的情况下&#xff0c;动态的给该对象增加一些职责&#xff08;增加额外功能&#…...

计算机竞赛 题目:基于深度学习的手势识别实现

文章目录 1 前言2 项目背景3 任务描述4 环境搭配5 项目实现5.1 准备数据5.2 构建网络5.3 开始训练5.4 模型评估 6 识别效果7 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的手势识别实现 该项目较为新颖&#xff0c;适合作为竞赛课题…...

手撕各种排序

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;掌握每种排序的方法&#xff0c;理解每种排序利弊…...

探索光的世界:Ray Optics Simulation 几何光学仿真平台深度解析

探索光的世界&#xff1a;Ray Optics Simulation 几何光学仿真平台深度解析 【免费下载链接】ray-optics A web app for creating and simulating 2D geometric optical scenes, with a gallery of (interactive) demos. 项目地址: https://gitcode.com/gh_mirrors/ra/ray-op…...

Path of Building PoE2:零基础掌握流放之路2角色规划工具实战指南

Path of Building PoE2&#xff1a;零基础掌握流放之路2角色规划工具实战指南 【免费下载链接】PathOfBuilding-PoE2 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding-PoE2 你是否曾遇到这样的困境&#xff1a;花费数小时规划的角色build&#xff0c…...

Phi-3-mini-4k-instruct-gguf实战教程:开箱即用的轻量中文问答部署指南

Phi-3-mini-4k-instruct-gguf实战教程&#xff1a;开箱即用的轻量中文问答部署指南 1. 认识Phi-3-mini-4k-instruct-gguf Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本。这个模型特别适合处理中文问答、文本改写、摘要整理以及简短创作等任务。…...

GLM-5.1 全面支持与 Gemini CLI 集成:HagiCode 的多模型进化之路

GLM-5.1 全面支持与 Gemini CLI 集成&#xff1a;HagiCode 的多模型进化之路 本文介绍了 HagiCode 平台近期的重要更新——智谱 AI GLM-5.1 模型的全面支持&#xff0c;以及 Gemini CLI 作为第十个 Agent CLI 的成功集成。这两项更新进一步强化了平台的多模型能力和多 CLI 生态…...

深度学习环境搭建不再难:PyTorch 2.6镜像快速部署指南

深度学习环境搭建不再难&#xff1a;PyTorch 2.6镜像快速部署指南 1. 为什么选择PyTorch 2.6镜像 PyTorch作为当前最流行的深度学习框架之一&#xff0c;其2.6版本带来了显著的性能提升和新特性。但对于初学者来说&#xff0c;从零开始配置PyTorch环境往往面临诸多挑战&#…...

AI Agent工程师进阶指南:掌握核心技能,冲击高薪(P7-P8必备)!

本文详细介绍了AI Agent工程师的能力分层&#xff0c;从API调用工程师到系统设计工程师再到基础设施架构师&#xff0c;明确了不同层级的能力要求和市场现状。文章深入剖析了核心技术栈&#xff0c;包括向量数据库、RAG系统、Agent架构、Memory系统以及生产化工程等关键领域&am…...

良久团购报单查单小程序开发

需求分析与规划 明确小程序的核心功能&#xff1a;报单&#xff08;提交订单&#xff09;、查单&#xff08;查询订单状态&#xff09;、团购管理&#xff08;商品展示、拼团进度&#xff09;。 确定用户角色&#xff1a;普通用户&#xff08;参与团购&#xff09;、管理员&…...

Java中如何实现Excel跨工作表数据复制

本文介绍了如何在Java程序中有效地复制Excel工作表中的数据。许多Java开发人员需要将数据从一个工作表复制到另一个工作表。本文提供了一个代码示例来帮助您解决这个问题。核心是如何在Java中有效地复制Excel工作表中特定区域的数据。下面的例子是使用Java库&#xff08;具体的…...

2026降AI工具实测:性价比/效果/安全选品指南

花了整整一周时间把市面5款主流降AI工具全维度测了一遍&#xff0c;从处理效果、定价、安全性三个核心维度做了横向对比。结论放在最前面&#xff1a;综合实力最强、毕业生首选的是SpeedAI科研小助手&#xff0c;性价比拉满&#xff0c;新手还能免费试用&#xff0c;完全适配绝…...

新手福音:用快马AI生成带详解注释的Arduino交通灯实验代码

作为一个刚接触单片机的新手&#xff0c;第一次看到Arduino开发板时既兴奋又迷茫。那些闪烁的LED灯和蜂鸣器背后到底藏着什么秘密&#xff1f;今天我就用InsCode(快马)平台来探索一个有趣的交通灯模拟项目&#xff0c;整个过程比想象中简单多了。 项目构思 我想做一个能模拟真实…...