发现一个问题,我们在同个session里面,把一条语句get出来,它会把对象放进一级缓存和二级缓存,但我在同个session再get一条同样的记录出来时,它只会去一级缓存找,找不到的话不会去二级缓存找了,这是为什么,如果从开个session的话,就会去二级缓存找,比如
s = HibernateSessionFactory.getSession();
user = (User) s.get(User.class, 1);
System.out.println("Put=" + st.getSecondLevelCachePutCount());
s.evict(user);
user = (User) s.get(User.class, 1);
这样会产生2条查询语句,但是执行完第一条是时候我做了个输出,发现已经是把第一条的记录放进了2级缓存的,
s.evict(user);只是把一级缓存清除了,并没有清除二级缓存,为什么第2条语句还是查数据库,
如果多开个session查就会去找 二级缓存,这是为什么啊
s = HibernateSessionFactory.getSession();
user = (User) s.get(User.class, 1);
System.out.println("Put=" + st.getSecondLevelCachePutCount());
s.evict(user);
user = (User) s.get(User.class, 1);
这样会产生2条查询语句,但是执行完第一条是时候我做了个输出,发现已经是把第一条的记录放进了2级缓存的,
s.evict(user);只是把一级缓存清除了,并没有清除二级缓存,为什么第2条语句还是查数据库,
如果多开个session查就会去找 二级缓存,这是为什么啊
<property name="generate_statistics">true</property>
然后在代码中
q.setCacheable(true);
结果我发现q.setCacheable(true);
好像是没有什么用的,因为就算把注释掉或改成flase,都会存入2级缓存,
只有把xml文件的设置去掉或改成flase才不会存入2级缓存,这样看的话
那
q.setCacheable(true);
还有什么用啊
XML配置文件:
<version name="version"></version><!-- 乐观锁配置 -->
类中定义了version
private int version;//乐观锁版本号public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}下面是运行代码:
Session s1 = null;
Session s2 = null;
Transaction tx1 = null;
Transaction tx2 = null;
try {
s1 = HibernateSessionFactory.getSessionFactory().openSession();
tx1 = s1.beginTransaction();
User user1 = (User) s1.get(User.class, id);
s2=HibernateSessionFactory.getSessionFactory().openSession();
tx2 = s2.beginTransaction();
User user2 = (User) s2.get(User.class, id);
user1.setFirstName("aaaaaaaaa");
user2.setFirstName("bbbbbbbbbbbb");
tx1.commit();
tx2.commit();
}catch(HibernateException e){
if (tx1!=null) {
tx1.rollback();
}
if (tx2!=null) {
tx2.rollback();
}
}finally{ if (s1 != null) {
s1.close();
}
if (s2 != null) {
s2.close();
}
}
}按道理来说应该发生错误,但是没发生,编译通过,大侠们救命
load才会使用二级缓存,而get则不使用
s1 = HibernateSessionFactory.getSessionFactory().openSession();
tx1 = s1.beginTransaction();User user1 = (User) s1.get(User.class, id);
user1.getName().setFirstName("222222");
System.out.println("hit=" + st.getSecondLevelCacheHitCount());
System.out.println("Miss=" + st.getSecondLevelCacheMissCount());
System.out.println("Put=" + st.getSecondLevelCachePutCount());
s2 = HibernateSessionFactory.getSessionFactory().openSession();//第一
tx1.commit();
User user2 = (User) s2.get(User.class, id); //第二
System.out.print(user2.getName().getFirstName());System.out.println("hit=" + st.getSecondLevelCacheHitCount());
System.out.println("Miss=" + st.getSecondLevelCacheMissCount());
System.out.println("Put=" + st.getSecondLevelCachePutCount());上面的代码大家帮我分析下,如果是这样写的,“第二”行的代码会去2级缓存拿数据,如果把“第一”的代码拉到“第二”行的前面,就不会去2级缓存拿数据了,而是直接去数据库拿,为什么会这样,我知道嵌套session不好,但是我在模拟乐观锁问题,希望各位大侠帮帮忙解释下
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。 http://baike.baidu.com/view/2273788.htm
而二级缓存对应的SessionFactory里面。
你重新起一个Session当时是去二级缓存里找啊。原来那个Session都关闭了,一级缓存也就没有了。
但是你的SessionFactory还是所以放到二级缓存里的东西还在。