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

优酷网站建设视频教程集阿里云速美建站

优酷网站建设视频教程集,阿里云速美建站,惠州建设公司网站,山东网站推广目录 一、业务场景 1、此时存在的问题 2、解决方案 3、为何要延时500毫秒#xff1f; 4、为何要两次删除缓存#xff1f; 二、代码实践 1、引入Redis和SpringBoot AOP依赖 2、编写自定义aop注解和切面 3、application.yml 4、user.sql脚本 5、UserController 6、U…目录 一、业务场景 1、此时存在的问题 2、解决方案 3、为何要延时500毫秒 4、为何要两次删除缓存 二、代码实践 1、引入Redis和SpringBoot AOP依赖 2、编写自定义aop注解和切面 3、application.yml 4、user.sql脚本 5、UserController 6、UserService 三、测试验证 1、ID10新增一条数据 2、第一次查询数据库Redis会保存查询结果 3、第一次访问ID为10 4、第一次访问数据库ID为10将结果存入Redis 5、更新ID为10对应的用户名验证数据库和缓存不一致方案 6、采用第二次删除 一、业务场景 在多线程并发情况下假设有两个数据库修改请求为保证数据库与redis的数据一致性修改请求的实现中需要修改数据库后级联修改Redis中的数据。 请求一A修改数据库数据 B修改Redis数据 请求二C修改数据库数据 D修改Redis数据 并发情况下就会存在A — C — D — B的情况 ❝ 一定要理解线程并发执行多组原子操作执行顺序是可能存在交叉现象的 ❞ 1、此时存在的问题 A修改数据库的数据最终保存到了Redis中C在A之后也修改了数据库数据。 此时出现了Redis中数据和数据库数据不一致的情况在后面的查询过程中就会长时间去先查Redis 从而出现查询到的数据并不是数据库中的真实数据的严重问题。 2、解决方案 在使用Redis时需要保持Redis和数据库数据的一致性最流行的解决方案之一就是延时双删策略。 注意要知道经常修改的数据表不适合使用Redis因为双删策略执行的结果是把Redis中保存的那条数据删除了以后的查询就都会去查询数据库。所以Redis使用的是读远远大于改的数据缓存。 延时双删方案执行步骤 删除缓存 更新数据库 延时500毫秒 (根据具体业务设置延时执行的时间) 删除缓存 3、为何要延时500毫秒 这是为了我们在第二次删除Redis之前能完成数据库的更新操作。假象一下如果没有第三步操作时有很大概率在两次删除Redis操作执行完毕之后数据库的数据还没有更新此时若有请求访问数据便会出现我们一开始提到的那个问题。 4、为何要两次删除缓存 如果我们没有第二次删除操作此时有请求访问数据有可能是访问的之前未做修改的Redis数据删除操作执行后Redis为空有请求进来时便会去访问数据库此时数据库中的数据已是更新后的数据保证了数据的一致性。 二、代码实践 1、引入Redis和SpringBoot AOP依赖 !-- redis使用 -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId /dependency !-- aop -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId /dependency 2、编写自定义aop注解和切面 ClearAndReloadCache延时双删注解 /***延时双删**/ Retention(RetentionPolicy.RUNTIME) Documented Target(ElementType.METHOD) public interface ClearAndReloadCache {String name() default ; }ClearAndReloadCacheAspect延时双删切面 Aspect Component public class ClearAndReloadCacheAspect {Autowired private StringRedisTemplate stringRedisTemplate;/** * 切入点 *切入点,基于注解实现的切入点 加上该注解的都是Aop切面的切入点 * */Pointcut(annotation(com.pdh.cache.ClearAndReloadCache)) public void pointCut(){} /** * 环绕通知 * 环绕通知非常强大可以决定目标方法是否执行什么时候执行执行时是否需要替换方法参数执行完毕是否需要替换返回值。 * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型 * param proceedingJoinPoint */ Around(pointCut()) public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){System.out.println(----------- 环绕通知 -----------);System.out.println(环绕通知的目标方法名 proceedingJoinPoint.getSignature().getName());Signature signature1 proceedingJoinPoint.getSignature();MethodSignature methodSignature (MethodSignature)signature1;Method targetMethod methodSignature.getMethod();//方法对象ClearAndReloadCache annotation targetMethod.getAnnotation(ClearAndReloadCache.class);//反射得到自定义注解的方法对象String name annotation.name();//获取自定义注解的方法对象的参数即nameSetString keys stringRedisTemplate.keys(* name *);//模糊定义keystringRedisTemplate.delete(keys);//模糊删除redis的key值//执行加入双删注解的改动数据库的业务 即controller中的方法业务Object proceed null;try {proceed proceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}//开一个线程 延迟1秒此处是1秒举例可以改成自己的业务// 在线程中延迟删除 同时将业务代码的结果返回 这样不影响业务代码的执行new Thread(() - {try {Thread.sleep(1000);SetString keys1 stringRedisTemplate.keys(* name *);//模糊删除stringRedisTemplate.delete(keys1);System.out.println(-----------1秒钟后在线程中延迟删除完毕 -----------);} catch (InterruptedException e) {e.printStackTrace();}}).start();return proceed;//返回业务代码的值} } 3、application.yml server:port: 8082spring:# redis settingredis:host: localhostport: 6379# cache settingcache:redis:time-to-live: 60000 # 60sdatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/testusername: rootpassword: 1234# mp setting mybatis-plus:mapper-locations: classpath*:com/pdh/mapper/*.xmlglobal-config:db-config:table-prefix:configuration:# log of sqllog-impl: org.apache.ibatis.logging.stdout.StdOutImpl# humpmap-underscore-to-camel-case: true 4、user.sql脚本 用于生产测试数据 DROP TABLE IF EXISTS user; CREATE TABLE user (id int(4) NOT NULL AUTO_INCREMENT,username varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 8 CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT Dynamic;-- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO user VALUES (1, 张三); INSERT INTO user VALUES (2, 李四); INSERT INTO user VALUES (3, 王二); INSERT INTO user VALUES (4, 麻子); INSERT INTO user VALUES (5, 王三); INSERT INTO user VALUES (6, 李三); 5、UserController /*** 用户控制层*/ RequestMapping(/user) RestController public class UserController {Autowiredprivate UserService userService;GetMapping(/get/{id})Cache(name get method)//Cacheable(cacheNames {get})public Result get(PathVariable(id) Integer id){return userService.get(id);}PostMapping(/updateData)ClearAndReloadCache(name get method)public Result updateData(RequestBody User user){return userService.update(user);}PostMapping(/insert)public Result insert(RequestBody User user){return userService.insert(user);}DeleteMapping(/delete/{id})public Result delete(PathVariable(id) Integer id){return userService.delete(id);} } 6、UserService /*** service层*/ Service public class UserService {Resourceprivate UserMapper userMapper;public Result get(Integer id){LambdaQueryWrapperUser wrapper new LambdaQueryWrapper();wrapper.eq(User::getId,id);User user userMapper.selectOne(wrapper);return Result.success(user);}public Result insert(User user){int line userMapper.insert(user);if(line 0)return Result.success(line);return Result.fail(3001,操作数据库失败);}public Result delete(Integer id) {LambdaQueryWrapperUser wrapper new LambdaQueryWrapper();wrapper.eq(User::getId, id);int line userMapper.delete(wrapper);if (line 0)return Result.success(line);return Result.fail(3001, 操作数据库失败);}public Result update(User user){int i userMapper.updateById(user);if(i 0)return Result.success(i);return Result.fail(3001,操作数据库失败);} }三、测试验证 1、ID10新增一条数据 2、第一次查询数据库Redis会保存查询结果 3、第一次访问ID为10 4、第一次访问数据库ID为10将结果存入Redis 5、更新ID为10对应的用户名验证数据库和缓存不一致方案 数据库和缓存不一致验证方案 打个断点模拟A线程执行第一次删除后在A更新数据库完成之前另外一个线程B访问ID10读取的还是旧数据。 6、采用第二次删除 根据业务场景设置延时时间两次删除缓存成功后Redis结果为空。读取的都是数据库真实数据不会出现读缓存和数据库不一致情况。
http://www.zqtcl.cn/news/409568/

相关文章:

  • dedecms 金融类网站模板wordpress dux5.3
  • 学校网站源码wordpress向网站上传文件怎么做
  • 电子商务网站建设说课稿济南网站建设方案报价
  • 谈谈设计和建设网站体会wordpress header在哪
  • 360免费建站怎么进不去域名托管
  • 做网站视频存储网站建设有云端吗
  • 建网站如何上传南通 网站优化
  • 青海学会网站建设公司果汁网站模板
  • 10_10_网站建站怎么做网站链接支付
  • 九台网站甘肃网站优化
  • phpcms 网站源码建设银行科技中心网站首页
  • 营销型网站建设php源码无锡设计网站公司
  • 在线制作简历的网站绍兴seo全网营销
  • 个人做网站接装修活哪个网站好长沙企业网站建设分公司
  • 青岛网站制作辰星辰中国万网icp网站备案专题
  • 做淘宝相关网站上海网站建设做物流一
  • 服装配件网站建设 中企动力静态网站 后台
  • 做网站较好的框架网站建设的定位是什么
  • 如何保护自己的网站桂林医院网站建设
  • 产品品牌策划方案佛山网站优化美姿姿seo
  • 北京城建一建设发展有限公司网站大连在哪个省的什么位置
  • 北京知名网站建设公司排名学校诗歌网站建设
  • 个人做网站接装修活哪个网站好上海造价信息网官网
  • 网页上做网会员网站备案怎么写oa报表网站开发
  • 郑州服装网站建设网站的层级
  • 东莞建设网站制作怎么建立信息网站平台
  • 网站建设的公司服务手机上做ppt的软件
  • 体育网站模版爱站网
  • 建设部网站最新消息浏览器网站大全免费
  • 网站建设 选中企动力邯郸哪有做网站的公司