Hibernate中session的关闭问题
实现一个修改客户信心的功能,分为两部分:一、点击修改,跳转到后台,然后执行根据id查询客户信息的
操作,并将查询到的客户信息回显到前台。二、前台将修改完的信心提交到后台,后台执行对用户信息更新
的操作。两部分的service层的代码如下:
第一部分,根据客户id查找客户信息
public Customer serachCustomerById (Customer customer) {
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
try {
UserDao dao = new UserDaoImpl();
customer = dao.serachCustomerById(customer);
tr.commit();
} catch (Exception e) {
tr.rollback();
throw new RuntimeException(e);
}
return customer;
}
第二部分,根据前台传回的数据对客户信息更新
public void updateCustomer (Customer customer) {
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
try {
UserDao dao = new UserDaoImpl();
dao.updateCustomer(customer);
tr.commit();
} catch (Exception e) {
tr.rollback();
throw new RuntimeException(e);
}
}
在上面的过程中存在这样几个问题:
1.为什么使用Hibernate框架就必须开启事务
2.为什么查询操作还有提交事务
3.为什么我们没有关闭session
1.为什么使用Hibernate框架就必须开始事务
在我们启动项目的时候,Hibernate框架会默认的帮我们将mysql数据库的自动提交事务关闭,
这样我们在使用jdbc操作数据库的时候,只是在内存中操作的对应的表,而操作完成后并没有
提交事务,这样我们队数据的操作相当于没有保存到硬盘上,所以我们必须要提交事务,提交
事务的前提就是获取事务对象,在hibernate框架中,要想获取事务对象,可以通过sesssion的
beginTranscation()方法获取,这样在执行完操作后,将事务提交,就可以对我们的操作进行
持久化。
2.为什么查询操作还要提交事务
以上面的修改客户信息为例,如果我们执行完第一部分后没有①处的提交操作,这个时候我们的
session就没有关闭,并且是和我们的当前线程绑定在一起的,里面的一级缓存中存储着我们
查询的客户的信息,用户修改完信息后将信息提交,在第二部我们获取session时获取的当前线程
绑定的session,如果两次请求执行的时间差很短的话,浏览器就会使用同义词线程,所以还是第
一次的session,这时如果利用hibernate执行更新操作,就会报错,因为session的一级缓存中
还存在着第一查询到的客户的信息,并且和我们这次要进行更新的客户的id是同一个,这样一个
因为存在持久态的对象和我们要操作的瞬时态对象有相同的id但是不是同一个对象,这样hibernate
就会报错。所以我们要在第一部分查询的时候要提交事务,将session关闭掉就可以避免这个问题。
所以无论增删该查都要提交事务。
3.为什么我们没有自己关闭session
hibernate框架会维护这个session,他会在你事务提交的时候关闭session。