论坛首页 Java企业应用论坛

大家说说关于hibernate的二级缓存跟查询缓存

浏览 8358 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-11-28  
  大家好,最近做的项目,打算用 hibernate 与其中的二级缓存,首先,项目背景如下:
  业务上的很简单,说白了,是一个人力资源系统;
  使用人数大约在2000人左右。
  数据关系分为部门,用户,工作组,角色,资源(权限过滤用的)等。当然还有一些其它,不细说;

  现在用hibernate  的二级缓存。但发现有不少的问题,其中最主要的问题就是脏数据的问题,可能是我用得不好,不过以下这个问题要如何处理?

  资源中,分类别,类别分组,组中挂资源,如果我进行以下操作,会出现脏数据:
  
   1. 通过类别,组,加载资源
   2. 删除资源(直接删除,没通过类别中的set<组>,组中的set<资源>删除)
   3. 再重复第一步操作

这时候就会出现脏数据,因为数据库中是已经删掉了,但缓存中类别,组中的set的数据还在!



  上面只是提出一个具体问题进行讨论,这里主要不是要向大家提问这个具体问题,而是想让大家发表对hibernate的二级缓存的看法,调查一下用hibernate二级缓存(包括查询缓存)的人多不多,还有最好是怎么去用,怎么去设计?也请各位指点一下,谢谢~
   发表时间:2012-11-28   最后修改:2012-11-28
我认为主要是删除资源没有同步cache

(1)关键:因为你的业务涉及read-write操作,所以要保证read-write在一个transactional的操作。
(2)以为hibernate的secondary cache需要第三方cache 组件support,所以你要确定你用的是哪种cache,比如EHCache OSCache等
(3)如果想要保证数据一致性,需要Cache Component支持事务性缓存策略实现。目前大都流行的框架都是支持读写事物,参考这个属性配置:hibernate.transaction.manager_lookup_class,它指定了一个事务管理的类,用来保证数据一致性。
(4)上一点只能保证单机部署,如果集群的话,需要考虑加锁的方式
0 请登录后投票
   发表时间:2012-11-28  
cectsky 写道
我认为主要是删除资源没有同步cache

(1)关键:因为你的业务涉及read-write操作,所以要保证read-write在一个transactional的操作。
(2)以为hibernate的secondary cache需要第三方cache 组件support,所以你要确定你用的是哪种cache,比如EHCache OSCache等
(3)如果想要保证数据一致性,需要Cache Component支持事务性缓存策略实现。目前大都流行的框架都是支持读写事物,参考这个属性配置:hibernate.transaction.manager_lookup_class,它指定了一个事务管理的类,用来保证数据一致性。
(4)上一点只能保证单机部署,如果集群的话,需要考虑加锁的方式

cectsky 你好,谢谢回复:

1. 目前可以保证在一个事务中read-write操作,但二级缓存是跨transaction的,比如,现在直接删除一个子实体(不通过根实体删除),那么根实体中的set缓存区是不知道该子实体被删除的,所以,下个transaction被删除的时候依然会查出这个子实体

2. 目前采用ehcache

4. 如果只考虑单机部署的话~

请问你们现在用二级缓存都是怎么用的呢?用得多吗?有遇到什么问题没?
0 请登录后投票
   发表时间:2012-11-28  
Hibernate 的cache 实现都对cache flush 的机制做了保证的, 这个本身不是问题。

你这个脏数据的问题是否和web app 集群下发生的?
0 请登录后投票
   发表时间:2012-11-28  
一江春水邀明月 写道
Hibernate 的cache 实现都对cache flush 的机制做了保证的, 这个本身不是问题。

你这个脏数据的问题是否和web app 集群下发生的?

您好,可否介绍一下hibernate cache对cache flush 的机制的保证吗?

不是web app集群环境下,目前应用还比较简单~没有集群,而且数据库也没有多个应用使用。

这样说吧,如
@Cache(region="Group")
public class Group{
    @cache(region="group.items")
    private Set<Item> items;
}

@Cache(region="item")
public class Item{
    //......
}


public class ItemService{
    public void remove(Item item){
       dao.remove(item);// 这里的操作,不有通知group,此时再通过group拿items的时候,被删除的数据的信息还是存在的(估计也只保存ID之类,未知,这时再通过该ID到数据库拿,就出问题了~(对象找不到 ))
    }
}

以上代码即兴写,忽略语法问题,呵呵~

0 请登录后投票
   发表时间:2012-11-28  
To be honest, 很久以前用过hibernate,没用过secondary cache


1.首先对于你这种场景,放在二级cache中是不明智的(放在二级cache中是那些经常查询,很少修改,能够保证在同级别下的更新的数据)
2.可以在每次修改子实体的时候,进行对根实体通知,进行cache同步操作。此时就涉及一个read-write的同步机制,EHCache已经支持。这可能会造成一些性能损耗,当然你的web app并发2000,还算能接受吧。
3.可以对修改子实体的方法注入操作,也就是AOP,简便并且松耦合
0 请登录后投票
   发表时间:2012-11-28  
cectsky 写道
To be honest, 很久以前用过hibernate,没用过secondary cache


1.首先对于你这种场景,放在二级cache中是不明智的(放在二级cache中是那些经常查询,很少修改,能够保证在同级别下的更新的数据)
2.可以在每次修改子实体的时候,进行对根实体通知,进行cache同步操作。此时就涉及一个read-write的同步机制,EHCache已经支持。这可能会造成一些性能损耗,当然你的web app并发2000,还算能接受吧。
3.可以对修改子实体的方法注入操作,也就是AOP,简便并且松耦合

to cectsky

HI,您好, 其实现在的问题是,我最想实现的是hibernate二级缓存的可拔插

1. 是的,二级缓存的数据很少修改,目前我放到二级缓存的数据也是很少修改的,但这限于上线后运行一段时间,客户数据完善后。
2、3. 因为如果要手动更新,即使是用aop,但也要有这些同步的代码,而且如果有多对parent-child的话,那么就要有多个这样的代码,想问下大家做项目的时候也需要做这样的事情吗?


cectsky,你现在主要是做哪方面的项目,不知道是否方便介绍下你们的设计呢?谢谢~

0 请登录后投票
   发表时间:2012-11-29  
cnblsp2 写道
cectsky 写道
To be honest, 很久以前用过hibernate,没用过secondary cache


1.首先对于你这种场景,放在二级cache中是不明智的(放在二级cache中是那些经常查询,很少修改,能够保证在同级别下的更新的数据)
2.可以在每次修改子实体的时候,进行对根实体通知,进行cache同步操作。此时就涉及一个read-write的同步机制,EHCache已经支持。这可能会造成一些性能损耗,当然你的web app并发2000,还算能接受吧。
3.可以对修改子实体的方法注入操作,也就是AOP,简便并且松耦合

to cectsky

HI,您好, 其实现在的问题是,我最想实现的是hibernate二级缓存的可拔插

1. 是的,二级缓存的数据很少修改,目前我放到二级缓存的数据也是很少修改的,但这限于上线后运行一段时间,客户数据完善后。
2、3. 因为如果要手动更新,即使是用aop,但也要有这些同步的代码,而且如果有多对parent-child的话,那么就要有多个这样的代码,想问下大家做项目的时候也需要做这样的事情吗?


cectsky,你现在主要是做哪方面的项目,不知道是否方便介绍下你们的设计呢?谢谢~



目前做网管系统,用不到hibernate, 有好多知识都忘记了。

如果这个hibernate或EHCache没有内置的API解决,加code是不可避免了
0 请登录后投票
   发表时间:2012-11-29  
很明显,你们代码操作的思想还是对表而不是对对象。
items是Group的属性。你删除item,应该操作group而不是单独去操作item。
0 请登录后投票
   发表时间:2012-11-29  
魔力猫咪 写道
很明显,你们代码操作的思想还是对表而不是对对象。
items是Group的属性。你删除item,应该操作group而不是单独去操作item。

您好,非常感谢您的回复:
  的确我之前开发的时候,都是根据表的,应该说,以前的Hibernate的使用也是简单使用,真正面向对象地去使用很少,不过按照您的说法的话,是不是操作item的时候都要通过group去操作呢?

如果有三层或者多层,如:
GroupParent(Set<Group>),
Group(Set<Items>)
Item

那么删除item的时候,难道要先拿到parent.groups.get(x).items.remove(item)
吗?


呵呵,按照我对面向对象的理解,操作item的话,那应该是出现在item相应的模块中吧?

不对之处,还望指正,谢谢~
0 请登录后投票
论坛首页 Java企业应用版

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