前不久学习Hibernate时候在资料书上看到这样一句话“持久态对象在数据库中都有相对应的记录”,而后在有关于Session的save()方法的代码注释出又看到了另一句话“因为未提交事务,所以没有对数据库进行访问”。于是产生了疑惑。
接下来编写个测试程序:
public class Test implements Runnable{ public static Thread t1=new Thread(new Test()); public static Thread t2=new Thread(new Test()); public static Transaction tx=null; public static Session session=null; public static void main(String args[]){ try{ session=HibernateSessionFactory.getSession(); PrintInfofromDatabase(); tx=session.beginTransaction(); System.out.println("---开始事务成功---"); Dlb dlb=new Dlb("138438","sb1@sb1"); session.save(dlb); System.out.println("---save操作成功---"); PrintInfofromDatabase(); t1.start(); }catch(Exception e){ e.printStackTrace(); } } @Override public void run() { try { System.out.println("---线程开始休眠10S---"); Thread.sleep(10000); System.out.println("---线程结束休眠---"); System.out.println("开始commit操作"); tx.commit(); System.out.println("事务提交成功---"); PrintInfofromDatabase(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); if(tx!=null) tx.rollback(); } } public static void PrintInfofromDatabase(){}//通过JDBC查询数据库并打印 }
查看输出结果如下:
上图左边第二次select命令是在线程休眠期间执行的,可知save()命令在提交事务前并没有进行数据库操作。上面那句话“持久态对象在数据库中都有相对应的记录”让我们进入到这个误区的。
接着说一说其中究竟怎么操作的:Hibernate中提供Session级别的缓存,属于事务范围,且只存在于Session的生命周期中。当调用Session接口的save()、update()、saveorupdate()、get()等方法时,如果在Session的缓存中还不存在相应的对象,Hibernate就会把该对象加入到缓存中。Session接口提供两个管理缓存的方法。
- ecivt(object obj):用于将某个对象从Session的缓存中清除。
- clear():用于将一级缓存(Session级缓存)中的所有对象全部清除,但不包括操作中的对象。
值得一提的是flush()方法:强制更新缓存,并提交事务。(Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.)
编写测试程序,和查看API文档是解决问题的有效途径。HibernateAPI文档链接