问题描述

在cache系统中writeThrough和writeBehind是两个常用的模式。

writeThrough是指,当用户更新缓存时,自动将值写入到数据源。

writeBehind是指,在用户更新缓存后异步更新到数据源。

ehcache实现

ehcache内部有一个CacheWriter接口,这个接口实现了cache一系列生命周期的钩子函数。

只需要实现自定义的写贯穿方法就可以在更新缓存时将对象写入底层的数据源

    //自定义的CacheWriter
public class MyCacheWriter implements CacheWriter {
public void write(Element element) throws CacheException {
System.out.println("write->"+element.getObjectValue()); //write到数据层
}
public void writeAll(Collection elements) throws CacheException {
System.out.println("writeall"); //write到数据层
}
...
}
//cacheWriter的工厂方法
public class MyCacheWriterFactory extends CacheWriterFactory{
@Override
public CacheWriter createCacheWriter(Ehcache cache, Properties properties) {
return new MyCacheWriter(); //返回自定义的CacheWriter
}

再将writer(的工厂方法)配置到cache中

    <cache name="writerCache" maxEntriesLocalHeap="10">
<cacheWriter writeMode="write-through" maxWriteDelay="8"
rateLimitPerSecond="5" writeCoalescing="true" writeBatching="true"
writeBatchSize="20" retryAttempts="2" retryAttemptDelaySeconds="2">
<cacheWriterFactory class="echach2.MyCacheWriterFactory"
properties="test=1;" propertySeparator=";" />
</cacheWriter>
</cache>

可以看到CacheWrite关于write有两个方法,write和writeall,这是通过配置中的writeMode控制的当配置为write-through时会在每一次更新缓存时同步调用write方法。而如果设置为write-behind时则会根据maxWriteDelay调用writeall来讲这段时间的数据调用writeall。

ehcahce的自动load机制

常规的cache使用方法是

    if(cache.exist("key")){
return cache.get("exist");
}else{
value=dao.get("key");
cache.put("key",value);
return value;
}

是在检测cache没有命中时从dao获得数据再跟新到缓存。

有以下两种办法可以减少这种复杂的编码

SelfPopulatingCache

在ehcache中有一套SelfPopulatingCache机制,它可以在缓存miss的情况下load底层数据

    //cache load工厂
public class MyCacheEntryFactory implements CacheEntryFactory {
public Object createEntry(Object key) throws Exception {
return new String("autoload "+key); //自定义load方法
}
}
//cache的装饰者工厂类
public class MyCacheDecoratorFactory extends CacheDecoratorFactory{
@Override
public Ehcache createDecoratedEhcache(Ehcache cache, Properties properties) {
return new SelfPopulatingCache(cache, new MyCacheEntryFactory());//使用SelfPopulatingCache并注册MyCacheEntryFactory
}

并在cache配置文件cache层中配置

    <cacheDecoratorFactory class="echach2.MyCacheDecoratorFactory"/>

这样获得的cache就会是经过装饰工厂生成的cache了

SelfPopulatingCache继承了BlockingCache,使用读写锁进行多线程更新和读取cache内容。

下面展示一下调用的代码

    @Test
public void readWriteThroughCache() throws InterruptedException {
CacheManager cache = CacheManager.create("cache.xml");
Ehcache readWriteCache = cache.addCacheIfAbsent("writerCache");
System.out.println("unexist key->"+readWriteCache.get(2).getObjectValue()); //自动读取值
readWriteCache.putWithWriter(new Element(1, "value")); //写贯穿a需调用putWithWriter
cache.shutdown();
}

输出为

    unexist key->autoload 2
write->value

使用getWithLoader

cache类拥有getWithLoader方法,它可以调用传入的loader对象进行数据load。但需要将get都改成这个方,而且对多线程同时写数据没有进行阻塞。

小结

以上介绍了ehcahe中write-thtough,write-behind与load-read的实现,可以在使用中适当选择数据加载及写入方式

ehcache2拾遗之write和load的更多相关文章

  1. ehcache2拾遗之cache持久化

    问题描述 应用在使用过程中会需要重启等,但是如果ehcache随着应用一起重启,那么刚重启的时候就会出现大量的miss,需要一定的访问量来重建缓存,如果缓存能够持久化,重启之后可以复用将会有助于缓解重 ...

  2. ehcache2拾遗之copyOnRead,copyOnWrite

    问题描述 缓存在提升应用性能,提高访问效率上都是至关重要的一步.ehcache也是广为使用的缓存之一.但是如果将一个可变的对象(如普通的POJO/List/Map等)存入缓存中,会导致怎样潜在的问题. ...

  3. Java 集合 HashMap & HashSet 拾遗

    Java 集合 HashMap & HashSet 拾遗 @author ixenos 摘要:HashMap内部结构分析 Java HashMap采用的是冲突链表方式 从上图容易看出,如果选择 ...

  4. java:Hibernate框架4(延迟加载(lazy),抓取(fetch),一级缓存,get,load,list,iterate,clear,evict,flush,二级缓存,注解,乐观锁和悲观锁,两者的比较)

    1.延时加载和抓取: hibernate.cfg.xml: <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-co ...

  5. [C#.NET 拾遗补漏]08:强大的LINQ

    大家好,这是 [C#.NET 拾遗补漏] 系列的第 08 篇文章,今天讲 C# 强大的 LINQ 查询.LINQ 是我最喜欢的 C# 语言特性之一. LINQ 是 Language INtegrate ...

  6. load和initialize方法

      一.load 方法什么时候调用: 在main方法还没执行的时候 就会 加载所有类,调用所有类的load方法. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法. 在项目中使 ...

  7. "NHibernate.Exceptions.GenericADOException: could not load an entity" 解决方案

     今天,测试一个项目的时候,抛出了这个莫名其妙的异常,然后就开始了一天的调试之旅... 花了很长时间,没有从代码找出任何问题... 那么到底哪里出问题呢? 根据下面那段长长的错误日志: -- ::, ...

  8. Redis命令拾遗二(散列类型)

    本文版权归博客园和作者吴双共同所有,欢迎转载,转载和爬虫请注明原文地址 :博客园蜗牛NoSql系列地址  http://www.cnblogs.com/tdws/tag/NoSql/ Redis命令拾 ...

  9. hibernate的get和load的区别

    在hibernate中我们知道如果要从数据库中得到一个对象,通常有两种方式,一种是通过session.get()方法,另一种就是通过session.load()方法,然后其实这两种方法在获得一个实体对 ...

随机推荐

  1. 怎样防止重复发送 Ajax 请求?

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:长天之云链接:http://www.zhihu.com/question/19805411/answer/15465427来源 ...

  2. 讲解版的导航高亮(新手福利)原生JS

    1.先写样式: 导航的排版样式: 导航对应高亮样式: .d6000f{ background:red; } .d6000f a{ color:#fff; } 我这个地方导航高亮样式为背景红色,字体颜色 ...

  3. UI基础

    知识点一:OC不允许直接修改对象的结构体属性的成员,允许直接修改对象的结构体属性 示例代码: CGRect tempFrame = self.frame; tempFrame.origin.x += ...

  4. JS-sort排序

    var arr = [ 'c', 'd', 'a', 'e' ];// arr.sort();// alert( arr );var arr2 = [ 4,3,5,5,76,2,0,8 ];// ar ...

  5. 学习maven的使用,看到一篇很实用的入门教程(菜鸟级入门)

    一.前言         早就知道maven 在java 项目的管理方面名声显赫,于是就想着学习掌握之,于是查阅了大量文档.发现这些文档的作者都是java 的大腕,大多都是站在掌握了一定maven 基 ...

  6. Python Charts库的使用

    博客园格式不太好看,可以去本人CSDN博客 http://blog.csdn.net/ashic/article/details/52598664 http://nbviewer.jupyter.or ...

  7. [转]彻底征服Word 2007标题多级列表

    [转]彻底征服Word 2007标题多级列表 用Word编写文档的人都知道,一篇长文档一般是需要分章节来划分段落的.在Word中也有对应的工具来完成这项任务,这就是多级列表.然而绝大多数使用Micro ...

  8. c1ctf2016 wp

    web: 1.web萌新福利 没啥好说的,右键查看源码得key 2.you are not admin 一看题目,就想到http头修改,常见的x-forwarded-for,referer,host, ...

  9. 20145301&20145321&20145335实验三

    20145301&20145321&20145335实验三 这次实验我的组员为:20145301赵嘉鑫.20145321曾子誉.20145335郝昊 实验内容详见:实验三

  10. 使用VirtualBox自带管理工具命令为虚拟磁盘扩展空间

    VirtualBox虚拟磁盘空间不够了,默认10G.想扩大,图形界面下没有找到可操作菜单.Google了一下用 Vbox自带的命令工具VBoxManage即可解决. C:\Program Files\ ...