hibernate中,调用session的save、delete、update方法后只是缓存到session里,应该什么时候使用transection的commit方法与数据库数据同步?如果每次调用sava、delete等方法提交一次,好像违背了hibernate的初衷,性能不好。但在网站开发时,添加一个用户信息、更新、或删除时,这些操作是要及时与数据库同步的。我的问题就是应在什么时候把数据提交到数据库。
 

      这就得根据你的业务需求来确定事务的边界,例如添加用户信息,添加完成以后就得commit,而不是继续操作等着更新或者其他操作以后才commit, 这和性能无关,得和你的业务逻辑来确定事务的边界

 /******************************************************************************************/

session.flush(): execute the SQL statements needed to synchronize the JDBC connection\’s
state with the state of objects held in memory.
This process, flush, occurs by default at the following points
• before some query executions
• from org.hibernate.Transaction.commit()
• from Session.flush()

处于persistent状态的bean,如果在session close之前,没有调用session.flush() 那么它的数据不会持久化到数据库中,即使做了commit(); 不过有一种情况比较特殊,就是transaction.commit()会先调用session.flush()方法。

sessionsave方法为例来看一个简单、完整的事务流程,如下是代码片段:

…………………………………………………………………………

 

Session session = sessionFactory.openSession();

 

Transaction tx = session.beginTransaction();

 

session.save(customer);//之前已实例化好了的一个对象

 

tx.commit();

 

…………………………………………………………………………

 

示例很简单,就是向数据库中插入一条顾客信息,这是一个最简单的数据库事务。在这个简单的过程中,Hibernate为我们做了一些什么事情呢?为了更好的观察,我们将Hibernateshow_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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

 

OIDinsert语句之前输出,这可以说明两个问题: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语句,但是数据库中并没有添加新的记录;

 

通过查阅HibernateAPI可以知道flush方法的主要作用就是清理缓存,强制数据库Hibernate缓存同步,以保证数据的一致性。它的主要动作就是向数据库发送一系列的sql语句,并执行这些sql语句,但是不会向数据库提交。而commit方法则会首先调用flush方法,然后提交事务。这就是为什么我们仅仅调用flush的时候记录并未插入到数据库中的原因,因为只有提交了事务,对数据库所做的更新才会被保存下来。因为commit方法隐式的调用了flush,所以一般我们都不会显示的调用flush方法。

(转http://blog.csdn.net/bzhang19841212/article/details/2167290)

版权声明:本文为zhll2046原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zhll2046/articles/2625689.html