ehcache2拾遗之write和load
问题描述
在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的更多相关文章
- ehcache2拾遗之cache持久化
问题描述 应用在使用过程中会需要重启等,但是如果ehcache随着应用一起重启,那么刚重启的时候就会出现大量的miss,需要一定的访问量来重建缓存,如果缓存能够持久化,重启之后可以复用将会有助于缓解重 ...
- ehcache2拾遗之copyOnRead,copyOnWrite
问题描述 缓存在提升应用性能,提高访问效率上都是至关重要的一步.ehcache也是广为使用的缓存之一.但是如果将一个可变的对象(如普通的POJO/List/Map等)存入缓存中,会导致怎样潜在的问题. ...
- Java 集合 HashMap & HashSet 拾遗
Java 集合 HashMap & HashSet 拾遗 @author ixenos 摘要:HashMap内部结构分析 Java HashMap采用的是冲突链表方式 从上图容易看出,如果选择 ...
- 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 ...
- [C#.NET 拾遗补漏]08:强大的LINQ
大家好,这是 [C#.NET 拾遗补漏] 系列的第 08 篇文章,今天讲 C# 强大的 LINQ 查询.LINQ 是我最喜欢的 C# 语言特性之一. LINQ 是 Language INtegrate ...
- load和initialize方法
一.load 方法什么时候调用: 在main方法还没执行的时候 就会 加载所有类,调用所有类的load方法. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法. 在项目中使 ...
- "NHibernate.Exceptions.GenericADOException: could not load an entity" 解决方案
今天,测试一个项目的时候,抛出了这个莫名其妙的异常,然后就开始了一天的调试之旅... 花了很长时间,没有从代码找出任何问题... 那么到底哪里出问题呢? 根据下面那段长长的错误日志: -- ::, ...
- Redis命令拾遗二(散列类型)
本文版权归博客园和作者吴双共同所有,欢迎转载,转载和爬虫请注明原文地址 :博客园蜗牛NoSql系列地址 http://www.cnblogs.com/tdws/tag/NoSql/ Redis命令拾 ...
- hibernate的get和load的区别
在hibernate中我们知道如果要从数据库中得到一个对象,通常有两种方式,一种是通过session.get()方法,另一种就是通过session.load()方法,然后其实这两种方法在获得一个实体对 ...
随机推荐
- 页面轮换,ViewFlipper 和 ViewPager 的区别
ViewFlipper继承ViewAnimator,切换view的时候是有动画效果的,适合做ppt,多界面的程序欢迎引导界面,算是个轻量级的组件,适合展示静态数据,少量数据. ViewPager继承V ...
- Python 第五天 递归,计算器(2)
利用函数编写如下数列: 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584, ...
- java的继承
1.什么是继承:一个类从另外一个类中得到成员.属性和行为方法等. 案例: //父类 public class Animal { // 变量 public int height=1; // 方法 pub ...
- mac下svn问题——“.a”(静态库)文件无法上传解决
mac下svn问题——“.a”(静态库)文件无法上传解决 “.a”(静态库)文件无法上传(svn工具:Versions) 网上查询了一下,说是Xcode自带的svn和Versi ...
- fcc
function spinalCase(str) { if(str.split(/\W|_/).length==1){ for(var i=0;i<str.length;i++){ if(/[A ...
- SQL Server 事务、异常和游标
转自:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110325.html Ø 事务 在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整 ...
- Celery Running Environment
After running celery in my machine, I got this: Running a worker with superuser privileges when the ...
- 【react学习笔记】-jsx
//jsx定义组件 var Divider = React.creatClass({ getIsComplete:function(){ return 'is-complete' }, handleC ...
- ElasticSearch学习笔记-02集群相关操作_cat参数
_cat参数允许你查看集群的一些相关信息,如集群是否健康,有哪些节点,以及索引的情况等的. 检测集群是否健康 curl localhost:9200/_cat/health?v 说明: curl 是一 ...
- Java Servlet与Web容器之间的关系
自从计算机软件开发进入网络时代,就开始涉及到通讯问题.在客户/服务器(也叫C/S应用)时期,每个软件都有自己的客户端和服务器端软件.并且客户端和服务器端之间的通讯协议差别也很大.后来随着互联网的发展, ...