Flex + Java 中小型项目的代码结构研究(二)(如何在业务层管理你的Cache)
Flex Structure 2
如何在业务层管理你的Cache
上次初步研究了一下前台与后台的关系,但还遗留了一个Server端的Cache问题。
关键字:EHCache, Spring Interceptor, Spring Advice, Java Annotation
前言
在看过很多的Cache的文章和讨论后,我是这样使用Cache的
1.在Session的生命周期内使用Hibernate的First Level Cache来缓存对象(数据访问层,细粒度缓存)
2.使用EHCache对Value Object在业务层做缓存(粗粒度缓存,写代码实现)
为什么我不想使用Hibernate的二级缓存呢?主要有以下几点思考
为了提高它的性能,我们把Cache和持久层关连起来,值得吗?
有必要所有的地方都做Cache吗?这些性能的提升是客户想要的吗?
哪些地方需要做Cache不是只有业务层才知道吗?
关于Hibernate二级缓存详细的介绍,大家还是看看下面几篇文章吧,讲得很好
分析Hibernate的缓存机制
http://www.enet.com.cn/article/2008/0115/A20080115110243.shtml
hibernate二级缓存攻略
http://www.iteye.com/topic/18904
Speed Up Your Hibernate Applications with Second-Level Caching
http://www.devx.com/dbzone/Article/29685/1954?pf=true
在现实生活中,在业务层做Cache又会有一些问题
在业务层需要做Cache的方法里要加上添加Cache或清除Cache的代码,这样不但做起来很麻烦,而且把Cache代码和业务逻辑混杂在一起。
在执行一个方法时,哪些关连的Cache需要被清除。如执行了UserBiz.update(userVO)后,需要清除findAll产生的所有Cache,同时也应该把id相同的findById产生的Cache清除。
下面的文章和代码也就是着重解决上面提到的问题
如附图所示,Spring会为所有的Biz方法加上MethodCacheInterceptor.java和MethodCacheAfterAdvice.java,当方法执行之前,Interceptor会对照Annotation的配置去看此方法的结果需不需要和有没有被Cache,然后决定是否直接从Cache中获得结果(如findAll方法)。而After Advice是在方法执行后决定是否要做一些Cache的清理工作(如update方法)。
具体的Annotation配置方法请参照后面的UserBiz.java
废话和理论还是少说点,上代码才是硬道理
ApplicationContext.xml
MethodCache.java1 楼 JavaJason 2008-02-20 我从写这些代码开始就有一个疑问,前面有OSCache, EHCache等等Framework来帮忙管理Cache,后面有Spring帮忙配置哪些方法需要做Cache。
那中间呢,为什么没有一些小的东东来帮忙配置如何管理Cache呢?Spring为什么不做这个?有什么问题吗?还是出于什么样的考虑?
希望了解这个的朋友能提点一二:) 2 楼 JavaJason 2008-02-21 突然想起来,之前Robin写过一篇文章说是要细粒度Cache,和我这里的思路有点不太一样,
如果没记错,他使用的是Ruby+Hibernate,所以他不要VO层的Cache,另外一点,就是他做的Cache比较全面,而我在这里用的只是粗粒度的,对于一个企业应用来说,有时候性能不会像JavaEye这么重要,考虑得多点的可能是工作量
大家有兴趣的可以把他那篇文章找出来读读 3 楼 lzmhehe 2008-03-20 没有想到cache 是这样用的,受教育了。
谢谢 4 楼 JavaJason 2008-04-01 有个朋友发消息给我,问了这两个问题,我觉得比较典型,所以就放上来了
1.如果项目很小,仅仅局域网使用,访问人数不是很多,同时在线不会超过100,是否有必要使用cache 和lazyload。
不要为了用Cache而去用Cache,只有当你在使用系统,或预计到会有性能问题的时候才去用它。
这篇文章中,我也介绍了怎么通过配置的方式使用Cache,代码和说明上面都有
这里的lazyload是为了让客户端的数据结构比较完整,而且同时避免加载不必要的数据
2.Model Locator 您在项目中否使用?我在demo中当session使用,如果不使用,您通过什么保存状态。
我之前有个项目也用了,也确实出现过一些bug
我建议能不用的地方就不要去用它,就像你在写C的时候也不会用很多的全局变量一样
要想保存状态,在各自的对象里面去保存,实在没办法才去用Model Locator
5 楼 hundred007 2008-08-04 一般来说缓存越接近前端效果越明显。比如jsp cache (html) > service > dao (hibernate二级缓存) > 数据库(oracle自身的缓存)。
但对应地,缓存越接近前端越难控制。hibernate二级缓存要求对数据库的独占。
显然,楼主这种service 缓存方法不但对数据库的独占,还要求对dao的独占,否则会导致读到的是脏数据。
还要注意一点使用了service 缓存就要保证入口的单一性,那就要求每个类的责任很明确了,A类做的事不能由B类去完成了,这需要域领域的分析能力。在公司里人员水平参差不齐,很难保证这点,所以service 缓存要小心。
就算能很好区分好各类的责任,也会很难控制service 缓存的正确性,时间一久,代码一多,什么都忘了。
如果只用service 缓存来处理保存,修改这种简单的操作,还不如直接用hibernate二级缓存。
互联网应用和企业应用有着很大的不同。互联网应用对数据的实时性不是很敏感。可以做些很接近前端的缓存,如页面静态化。
企业应用往往很关注数据的正确性。
个人认为声明也是代码,所以认为楼主的方法一样是Cache代码和业务逻辑写在一起,声明的效果相当于把Cache公用处理代码写在公用Util类。
以上是个人看法,大家多多讨论。 6 楼 BlueMeteorolite 2008-10-20 哦,只有JAVA端(Cache)的设计。兴趣不大。啥时候来个FLEX端的设计?