日期:2014-05-16  浏览次数:20467 次

FreyjaJdbcTemplate特性二:cache

在使用hibernate开发过程中,让我一直感到奇怪的是为什么缓存是如此的让人不顺心。对于update操作频繁的项目更是噩梦。这和我对缓存的理解有很大的出入。

我的想法有2点:

1、数据库是大海,缓存是池塘。如果我抓了4条鱼到池塘里面去,为什么我一直要做这么一件事情:把鱼抓到池塘里面过一段时间又放回大海,过一段时间又抓到池塘里面去。这样真傻。还有一个诡异的问题,鱼被抓到池塘里面了,大海里面的鱼是哪来的?

?

2、如果我要抓所有的鲶鱼,难道我只去池塘抓?如果我怎么才能知道池塘的鱼是不是就是所有的鲶鱼了,这个时候必须去大海里面再捞一捞。必须去大海里面一次又一次的捞?要池塘又是干嘛的?

?

?

freyja的做法:

?

1、在freyja里面鱼只有一条,要么在池塘要么在海里面。freyja用hashMap来管理缓存(ehcache)

2、get方式获取到的都是优先缓存内的值,取不到才会去发送sql并且放入cache中。

find()方法会发送sql去查找id,然后遍历缓存,如果缓存中存在者返回缓存中的值,否则取数据库中的。

executeUpdate()方法会直接update数据库,并且会select id 找出涉及到的表的id然后用el工具更新缓存中的值。来维护缓存。

?

将要实现的cache能力:

3、第一次发送sql会查询出一个记录集,第二次发送sql着直接取缓存中的内容。难点是,如果其中一条记录的条件变化,如何完成这个处理?我的想法是一条记录保存所有缓存他得key,一旦update操作则让其缓存失效(这个是简单做法,复杂做法是根据条件再次判断是否让缓存失效。)

?

4、(这是我最喜欢的一个功能)no update。

这个功能的特点就是在update(user)的时候不会去发送sql update数据库。也就是第一点所说的,鱼在池塘就不去理会大海。这个功能的思路大概有了,正在施工中。但是工作量很大,而且效率怎么样不得而之。总之,这是自寻死路。

?

对于现在的freyja来说不支持分布式,也许以后会去考虑,一旦支持了分布式那么我的第一个理念就有出入了。

?

其实还有最大的一个问题:事务

http://freyja.iteye.com/blog/1178182

?

事务的特性就是为了让一个人不要在看书的时候听音乐。因为同时做2件事的时候容易出问题。事务还是很有存在的必要的,但是freyja的结构让事务失去了作用。只有一个对象的freyja可以在事物里面的数据被事物外的数据修改。

?

freyja对事物的处理是,在get()实体的时候根据事物的id为key把结果集放入一个map作为副本,在出错的时候”回滚“,事物结束的时候remove key。这部分还在完善中。

?

在简单的测试中,hibernate一级缓存情况下的select update 操作freyja和hibernate效率相当。(因为freyja本身就是一个大的一级缓存)。但是到了重要的二级缓存里面hibernate和freyja没有可比性了。

?

如这么一个测试:@Test

	public void testFind() {
	
		
		long l1 = System.currentTimeMillis();
		for (int i = 0; i < 2000; i++) {
			userService.testFind();
			}
		long l2 = System.currentTimeMillis();
		System.out.println("freyja find() 5000个对象耗时:" + (l2 - l1) / 1000);
	}

public void testFind() {
		for (int i = 0; i < 10; i++) {
			List<User> list = baseDAO.find(User.class, "level < ?", i);
		}
	}

?

?

模拟二级缓存环境,数据源用的是同一个,hibernate的二级缓存开启查询缓存关闭(难道开启会好点?)

?

?

hibernate find() 5000个对象耗时:11 (500*10)

hibernate find() 5000个对象耗时:20 (1000*10)

hibernate find() 5000个对象耗时:40 (2000*10)

?

freyja find() 5000个对象耗时:7 (500*10)

freyja find() 5000个对象耗时:13 (1000*10)

freyja find() 5000个对象耗时:25 (2000*10)

?

分别是2000调用、1000次调用和500次调用。User表里面有5000条记录,level为1-5000;

?

这个差距大概体现在hibernate每次从缓存中提取结果需要序列化的原因。

?

还是等完全施工完毕再全面的系统测试一次比较好。

?

那个时候hibernate有它的一套完备的体系,freyja则有自己的原生sql+cache支持。

?

FreyjaJdbcTemplate特性一:HQL?

?

FreyjaJdbcTemplate特性二:cache

?

FreyjaJdbcTemplate特性三:JdbcTemplate?

?

?

1 楼 bitray 2011-12-13  
关注度太低了,属于楼主自娱自乐?还是打算搞成新的项目?
2 楼 aa87963014 2011-12-13  
等最后出来的时候 大家就能看到freyja有多强大了