在使用hibernate开发时,遇到最多的就是session与事务,那么他们两个有什么关系呢?下面我来抛砖引玉:java
一、session是hibernate中的以及缓存机制,是用来对数据进行增删改查的一个东西(具体是什么我也不是很清楚,能够理解为是用来操做数据的)mysql
二、事务是一组操做单元的集合,用的比较多的是conmmit和rollback这两个方法,前面的提交后面的回滚。sql
先看下面的两段代码:数据库
代码1:缓存
Configuration config = new Configuration().configure("com/ebookstore/config/hibernate.cfg.xml");
Session session = config.buildSessionFactory().openSession();
session
Transaction tran=session.beginTransaction();
tran.begin();框架
session.save(object);
tran.commit();
session.flush();测试
代码2:ui
Configuration config = new Configuration().configure("com/ebookstore/config/hibernate.cfg.xml");
Session session = config.buildSessionFactory().openSession();
spa
Object obj = session.get(dtoclass, id);
session.flush();
代码1:用到了事务,而代码二呢没有,这是怎么缘由呢?咱们能够从两个方面去理解:
一、在对数据进行查找时,即便你失败并不影响数据库中的数据;在对数据库进行添加时,那就不一样了,当你添加数据失败时,可能会在数据库中留下垃圾数据。这是咱们就要用到事务,事务他提交失败时,他就会自动回滚。这样就不影响数据库了。
二、在对hibernate框架使用时,你不从新开启事务的话,你是不能对数据进行增删改的,由于事务默认为是失败的,也就是数他一直处于回滚状态。因此你每次操做都是不成功的!
说了这么多,就是一句话,使用hibernate进行增删改是要从新开启事务,使用查询时能够不用从新开启事务!
2、
以session的save方法为例来看一个简单、完整的事务流程,以下是代码片断:
…………………………………………………………………………
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(customer);//以前已实例化好了的一个对象
tx.commit();
…………………………………………………………………………
示例很简单,就是向数据库中插入一条顾客信息,这是一个最简单的数据库事务。在这个简单的过程当中,hibernate为咱们作了一些什么事情呢?为了更好的观察,咱们将Hibernate的”show_sql”属性设置为true,而后运行咱们的程序,控制台打印出以下信息:
Hibernate: select max(ID) from CUSTOMER
Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
这里也许看不出什么端倪来,如今在session.save(customer)后面加一行代码,输出这个customer的OID,System.out.println(customer.getId()),再次运行程序,控制台输出为:
Hibernate: select max(ID) from CUSTOMER
22
Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
OID在insert语句以前输出,这能够说明两个问题:1.insert语句并非在执行save的时候发送给数据库的;2.insert语句是在执行commit的时候发送给数据库的。结合前面咱们所说过的:执行save的时候,Hibernate会首先把对象放入缓存,而后计划一条insert语句。一个基本的插入流程就出来了:
1. 判断所要保存的实例是否已处于持久化状态,若是不是,则将其置入缓存;
2. 根据所要保存的实例计划一条insert sql语句,注意只是计划,并不执行;
3. 事务提交时执行以前所计划的insert语句;
后台还打印出了select max(ID) from CUSTOMER,这主要是为了给customer赋予一个OID,由于通常状况下临时对象的OID是NULL。
接着咱们作两个测试:
1. 将tx.commit();注释掉,此时控制台没有打印出insert语句;
2. 将tx.commit()换成session.flush,此时控制太打印出了insert语句,可是数据库中并无添加新的记录;
经过查阅Hibernate的API能够知道flush方法的主要做用就是清理缓存,强制数据库
与Hibernate缓存同步,以保证数据的一致性。它的主要动做就是向数据库发送一系列的sql语句,并执行这些sql语句,可是不会向数据库提交。而commit方法则会首先调用flush方法,而后提交事务。这就是为何咱们仅仅调用flush的时候记录并未插入到数据库中的缘由,由于只有提交了事务,对数据库所作的更新才会被保存下来。由于commit方法隐式的调用了flush,因此通常咱们都不会显示的调用flush方法。