论坛首页 Java企业应用论坛

用观察者模式解决点击一次文章 update一次数据库的问题

浏览 11748 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-03-14  

接上文http://xuliangyong.iteye.com/blog/171240

对于第二种方法现用观察着模式来解决

思路是这样:当点击a文章(id=1234)够10次后 ,通知文章管理器更新点击次数

update article set hit_count = hit_count+10 where id = 1234

这样就减少了访问数据库的次数

 

代码如下:

public class HitCached extends Observable{
	private static final int DEFAULT_MAX_HITS = 10;
	private Map<Long, Integer> hits = Collections.synchronizedMap(new HashMap<Long, Integer>());
	
	/**
	 * 最大点击量。超过该值就更新数据库
	 */
	private int maxHits = DEFAULT_MAX_HITS;
	
	public HitCached(){}
	
	public HitCached(int maxHits){
		this.maxHits = maxHits;
	}
	
	public void put(Long key, Integer value){
		hits.put(key, value);
	}
	
	/**
	 * 为指定key 增加指定的点击量
	 * @param hitIncreased 增加的点数 
	 */
	public void addHit(Long key, Integer hitIncreased){
		if( !hits.containsKey(key) )
				hits.put(key, 0);
		Integer value = hits.get(key);
		if(value + hitIncreased >= maxHits){
			setChanged();
			notifyObservers(KeyValuePair.create(key, value + hitIncreased));
			hits.remove(key);
		}else{
			hits.put(key, value + hitIncreased);
		}
		
	}
	
	public Integer get(Long key){
		return hits.get(key);
	}
	
	public void clear(){
		hits.clear();
	}
	
}
 
public class ArticleManagerImpl extends HibernateGenericDao<Article, Long> implements ArticleManager ,Oberver{
	
	public void update(Observable o, Object arg){
		KeyValuePair keyValue = (KeyValuePair)arg;
		Article article = this.get(keyValue.getKey());
		article.setHitCount(article.getHitCount() + keyValue.getValue());
		save(article);
	}
 

 

action中调用

private static HitCached hitCached = new HitCached(5);

public String view() {
		if (id != null){
			entity = articleManager.get(id);
			hitCached.addObserver(articleManager);
			hitCached.addHit(id, 1);
		}
}

 这样没十次查看才update一次数据库 更新一次缓存 性能得到了大的提升

存在的问题:

停止服务会丢失一些数据 可加一个监听器 来处理

   发表时间:2008-03-14  
把下面这段代码放到/articles/1234的页面中不是更好么?

<script type="text/javascript" src="/counter/articles/1234"></script>
0 请登录后投票
   发表时间:2008-03-14  
只在cache中放点击次数,当点击次数被10整除时候,再flush到数据库不是更好么?
0 请登录后投票
   发表时间:2008-03-14  
Readonly 写道
只在cache中放点击次数,当点击次数被10整除时候,再flush到数据库不是更好么?



cache中存放点击数有两种思路:
1.只存放自上次flush后的新增的点击次数,flush之后置为0。集群环境下这样可以采取local cache。

2.初始化时获取原点击次数,flush之后保留原值。集群环境下只能用central cache。

感觉1更好一些。
1 请登录后投票
   发表时间:2008-03-14  
sorphi 写道
把下面这段代码放到/articles/1234的页面中不是更好么?

<script type="text/javascript" src="/counter/articles/1234"></script>

怎样的思路? 没看明白
2 请登录后投票
   发表时间:2008-03-14  
我的意思是,记录并更新点击数的行为,放在单独的counter应用中来实现,在业务层解耦。
0 请登录后投票
   发表时间:2008-03-14  
sorphi 写道
我的意思是,记录并更新点击数的行为,放在单独的counter应用中来实现,在业务层解耦。

思路不错
不过貌似跟缓存没直接关系
0 请登录后投票
   发表时间:2008-03-14  
cache还是需要维护的吧,好比你一个系统有几十万活动帖子。某些冷门帖子被点了一次(好比检索结果),在很长一段时间都不会点过10次,cache岂不是越来越大?
0 请登录后投票
   发表时间:2008-03-14  
myreligion 写道
cache还是需要维护的吧,好比你一个系统有几十万活动帖子。某些冷门帖子被点了一次(好比检索结果),在很长一段时间都不会点过10次,cache岂不是越来越大?

加上定时flush?
0 请登录后投票
   发表时间:2008-03-15  
同步怎么办
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics