文档章节

使用Spring4.3解决缓存过期后多线程并发访问数据库的问题

孟飞阳
 孟飞阳
发布于 2017/02/16 14:29
字数 475
阅读 24
收藏 0
点赞 0
评论 0

 

缓存过期之后,如果多个线程同时请求对某个数据的访问,会同时去到数据库,导致数据库瞬间负荷增高。Spring4.3为@Cacheable注解提供了一个新的参数“sync”(boolean类型,缺省为false),当设置它为true时,只有一个线程的请求会去到数据库,其他线程都会等待直到缓存可用。这个设置可以减少对数据库的瞬间并发访问。
不过不一定所有的缓存系统都支持这个配置。经过验证,Guava Cache是支持的。验证过程如下:

1、Guava Cache配置,参考:http://blog.csdn.net/clementad/article/details/51250472

2、创建从数据库获取数据的类和方法,该方法使用@Cacheable注解:

@Service  
public class UserServiceCacheablesImpl implements UserServiceCacheables{  
    private final static Logger logger = LoggerFactory.getLogger(UserServiceCacheablesImpl.class);  
  
    @Autowired  
    UserDAO userDAO;  
      
    @Override  
    @Cacheable(value="getPhoneNoByUserId")  
    public String getPhoneNoByUserId(int userId) {  
        logger.debug("getting data from database, userId={}", userId);  
        return userDAO.getPhoneNoByUserId(userId);  
    }  
}  

3、创建多线程并发的单元测试代码:

@RunWith(SpringRunner.class)  
@SpringBootTest  
public class AdminApplicationTests {  
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());  
  
    @Autowired  
    UserServiceCacheables userServiceCacheables;  
      
    /** 
     * 多线程并发测试 
     */  
    @Test  
    public void multiThreads() throws Exception{  
        int number = 3; //线程数  
        ExecutorService executorService = Executors.newFixedThreadPool(number);  
          
        List<Future<String>> results = new ArrayList<Future<String>>();  
        int userId = 26358;  
          
        for (int i=0; i < number; i++) { //非阻塞地启动number个线程,由Future接收结果  
            Future<String> future = executorService.submit(new MyThread(userId));  
            //Thread.sleep(300);  
            results.add(future);  
        }  
          
        for(Future<String> f : results){ //从Future中获取结果,打印出来  
            String phoneNo = f.get();  
            logger.debug(phoneNo);  
        }  
    }  
      
    class MyThread implements Callable<String>{  
        int userId;  
          
        public MyThread(int userId) {  
            this.userId = userId;  
        }  
          
        @Override  
        public String call() throws Exception {  
            return userServiceCacheables.getPhoneNoByUserId(userId);  
        }  
    }  
}  


4、测试结果:
当设置3个并发线程的时候,会出现3个log:“getting data from database, userId=26358”,说明访问了3次数据库。
当修改注解如下之后,只出现一次“getting data from database, userId=26358”,说明只访问了1次数据库,另外两次命中了缓存:

@Cacheable(value="getPhoneNoByUserId", sync=true)  

 

本文转载自:http://blog.csdn.net/clementad/article/details/52452119

共有 人打赏支持
孟飞阳
粉丝 202
博文 923
码字总数 537449
作品 5
朝阳
个人站长
缓存写法总结

基本写法 为了方便演示,这里使用Runtime.Cache做缓存容器,并定义个简单操作类。如下: 简单读取: 在项目中,有不少这样写法,这样写并没有错,但在并发量上来后就容易出问题。 缓存雪崩 ...

吞吞吐吐的
2017/09/26
0
0
缓存相关——缓存穿透、缓存并发、缓存失效、缓存预热、缓存雪崩、缓存算法

一、缓存穿透 我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查询的某一个数据在缓存...

空云万里晴
2016/06/16
1K
0
缓存穿透、缓存并发、热点缓存之最佳招式

一、前言 我们在用缓存的时候,不管是Redis或者Memcached,基本上会通用遇到以下三个问题: 缓存穿透 缓存并发 缓存失效 缓存穿透 注: 上面三个图会有什么问题呢? 我们在项目中使用缓存通常...

程超
2017/12/26
0
0
面对海量请求,缓存设计还应该考虑哪些问题?

  【IT168 技术】从第一个缓存框架 Memcached 诞生以来,缓存就广泛地存在于互联网应用中。如果你的应用流量很小,那么使用缓存可能并不需要做多余的考虑。但如果你的应用流量达到了成百上...

博客园
05/23
0
0
Redis查漏补缺:最易错过的技术要点大扫盲

作者介绍 孤独烟,中国平安研发工程师,目前负责规则云平台架构设计以及需求研发工作。毕业后一直从事Java开发工作,在Web开发、架构设计上有多年的实战经验。在MySQL性能优化、JVM调优、分布...

孤独烟
06/25
0
0
面对海量请求,缓存设计还应该考虑哪些问题?

从第一个缓存框架 Memcached 诞生以来,缓存就广泛地存在于互联网应用中。如果你的应用流量很小,那么使用缓存可能并不需要做多余的考虑。但如果你的应用流量达到了成百上千万,那么你就不得...

陈树义
05/15
0
0
Redis 总结精讲 看一篇成高手系统-4

本文围绕以下几点进行阐述 1、为什么使用redis 2、使用redis有什么缺点 3、单线程的redis为什么这么快 4、redis的数据类型,以及每种数据类型的使用场景 5、redis的过期策略以及内存淘汰机制...

kuchawyz
07/02
0
0
【转 :Hibernate 缓存机制】

转自:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html Hibernate 缓存机制 一、why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库。 为了降低...

angel挤一挤
2017/02/13
0
0
Hibernate缓存策略详解

Hibernate缓存策略 1. 数据缓存 1.1. 概述 缓存是数据库数据临时容器,它包含了库表数据的临时拷贝,位于数据库与数据访问层之间。 ORM 在进行数据读取时,会根据其缓存管理策略,首先在内存...

提广乾
2012/09/11
0
0
亿级请求下多级缓存那些事

什么是多级缓存 所谓多级缓存,即在整个系统架构的不同系统层级进行数据缓存,以提升访问效率,这也是应用最广的方案之一。我们应用的整体架构如图1所示: 图1 多级缓存方案 整体流程如上图所...

技术小能手
01/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

20位活跃在Github上的国内技术大牛 leij 何小鹏 亚信

本文列举了20位在Github上非常活跃的国内大牛,看看其中是不是很多熟悉的面孔? 1. lifesinger(玉伯) Github主页: https://github.com/lifesinger 微博:@ 玉伯也叫射雕 玉伯(王保平),...

海博1600
9分钟前
0
0
高性能服务器本质论

一 服务器分类 从软件性能角度,高性能服务器分:cpu密集型服务器/IO密集型服务器 (1)CPU密集型:该类服务器没有对io的访问/没有同步点,性能瓶颈在于对cpu的充分利用。 典型的如转发服务器/...

码代码的小司机
10分钟前
0
0
Mybatis收集配置

一、Mybatis取Clob数据 1、Mapper.xml配置 <resultMap type="com.test.User" id="user"> <result column="id" property="id"/> <result column="json_data" property="jsonData" ......

星痕2018
35分钟前
0
0
centos7设置以多用户模式启动

1、旧版本linux系统修改inittab文件,在新版本执行vi /etc/inittab 会有以下提示 # inittab is no longer used when using systemd. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON......

haha360
今天
0
0
OSChina 周日乱弹 —— 局长:怕你不爱我

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ andonny :分享周二珂的单曲《孤独她呀》 《孤独她呀》- 周二珂 手机党少年们想听歌,请使劲儿戳(这里) @孤星闵月 :没事干,看一遍红楼梦...

小小编辑
今天
181
9
Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式 Factory工厂模式 Singleton单例模式 Delegate委派模式 Strategy策略模式 Prototype原型模式 Template模板模式 Spring5 beans 接口实例化 代理Bean操作 ...

小致dad
今天
0
0
SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
11
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
17
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
251
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部