cache of the Session flush clear

Whenever you pass an object to save(), update() or saveOrUpdate(), and whenever you retrieve an object usingload(),get(),list(),iterate() or scroll(), that object is added to the internal cache of theSession.

When flush() is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur, or if you are processing a huge number of objects and need to manage memory efficiently, the evict() method can be used to remove the object and its collections from the first-level cache.

Example 21.9. Explcitly evicting a cached instance from the first level cache usingSession.evict()

while ( cats.next() ) {

    Cat cat = (Cat) cats.get(0);

    doSomethingWithACat(cat);

    sess.evict(cat);

}


 
The Session also provides a contains() method to determine if an instance belongs to the session cache.

To evict all objects from the session cache, call Session.clear()

flush

void flush()
           throws HibernateException
Force this session to flush. Must be called at the end of a unit of work, before committing the transaction and closing the session (depending on flush-mode, Transaction.commit() calls this method).

Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.

Throws:
HibernateException - Indicates problems flushing the session or talking to the database.

 

clear

void clear()
Completely clear the session. Evict all loaded instances and cancel all pending saves, updates and deletions. Do not close open iterators or instances of ScrollableResults.

 

@Test
	public void save() {
		ApplicationContext actionContext=new ClassPathXmlApplicationContext("beans.xml");
		SessionFactory sf =(SessionFactory) actionContext.getBean("mySessionFactory");
		Session session = sf.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = new Student();
		student.setId(Long.valueOf(3));
		student.setName("aa");
		
		session.save(student);
		//session.clear();   //加上则清空session                                                                                            		session.flush();   // 与数据库同步                                                                                     		transaction.commit();
		session.close();
	}

由于session caches的原因,

public void upload(){
		ApplicationContext actionContext=new ClassPathXmlApplicationContext("beans.xml");
		SessionFactory sf =(SessionFactory) actionContext.getBean("mySessionFactory");
		Session session = sf.openSession();
		Transaction transaction = session.beginTransaction();
		Student student = (Student) session.createQuery(" from Student s where s.id = 1").uniqueResult();  //1句
		Student student2 = (Student) session.createQuery(" from Student s where s.id = 1").uniqueResult(); //2句
		session.clear();                                                                                   //3句
		Student student3 = (Student) session.createQuery(" from Student s where s.id = 1").uniqueResult(); //4句
		transaction.commit();
		session.close();
	}

因为"1句"查出的student在session里面

所以如果1,2句之间我在数据库update id=1的student的名字

update student s set s.name='sl' where s.id=1;
commit;

二句是查不到的,确切的说是没检查name列,而是只检查了id主键,hibernate一看该id为1的student的对象在缓存里面,就不关心其他属性了,咱们看下hibernate生成的sql就明白了

Hibernate: select student0_.id as id3_, student0_.name as name3_ from student student0_ where student0_.id=1
21:04:23,166 TRACE BasicExtractor:71 - found [1] as column [id3_]
21:04:23,182 TRACE BasicExtractor:71 - found [dd] as column [name3_]
Hibernate: select student0_.id as id3_, student0_.name as name3_ from student student0_ where student0_.id=1
21:05:34,788 TRACE BasicExtractor:71 - found [1] as column [id3_]

可以看到只查询了id就没再查询

当我用3句情况session里面的对象之后,由于session里面没有此id的student的对象,hibernate会重新查询id为1的所有student表中的所有列,然后再把封装的student3对象放到session里

下面是hibernate在执行"4句"时生成的sql语句

Hibernate: select student0_.id as id3_, student0_.name as name3_ from student student0_ where student0_.id=1
21:05:50,966 TRACE BasicExtractor:71 - found [1] as column [id3_]
21:05:50,966 TRACE BasicExtractor:71 - found [sl] as column [name3_]

可见2个列都查询出来了,而我们update的"s1"的name列也查出来了

 所以虽然@transactional可以指定isolation=READ_COMMITTED

但是要先清除session里面该对象,再次查询该对象才能查询出其他transaction更改commit该对象的数据,即出现幻读

关于幻读可以看http://blog.csdn.net/wyxz126/article/details/8751926

 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值