hibernate框架绑定本地的session(八)
2017-11-18 23:45
453 查看
有这么一个业务:保存两个user,在dao层分别写两个方法,在service层调用这两个方法。要保证这两个方法在一个事务里面。
代码如下:
servlet
那么在service层开启事务,代码修改如下:
hibernate.cfg.xml添加一个配置项
HibernateUtils添加方法
service
Hibernate openSession() 和 getCurrentSession的区别
getHiberanteTemplate 、getCurrentSession和OpenSession
采用getCurrentSession()创建的Session会绑定到当前的线程中去、而采用OpenSession()则不会。
采用getCurrentSession()创建的Session在commit或rollback后会自动关闭,采用OpenSession()必须手动关闭。
采用getCurrentSession()需要在Hibernate.cfg.xml配置文件中加入如下配置:
如果是本地事物,及JDBC一个数据库:
<propety name=”Hibernate.current_session_context_class”>thread</propety>
如果是全局事物,及jta事物、多个数据库资源或事物资源:
<propety name=”Hibernate.current_session_context_class”>jta</propety>
使用spring的getHiberanteTemplate 就不需要考虑事务管理和session关闭的问题:
openSession创建session时autoCloseSessionEnabled参数为false,即在事物结束后不会自动关闭session,需要手动关闭,如果不关闭将导致session关联的数据库连接无法释放,最后资源耗尽而使程序当掉。
getCurrentSession创建session时autoCloseSessionEnabled,flushBeforeCompletionEnabled都为true,并且session会同sessionFactory组成一个map以sessionFactory为主键绑定到当前线程。
getCurrentSession():从上下文(配置文件current_session_context_class: thread 使用Connection自动管理;jta(java transaction api) 由Application Server提供的分布式事务管理,Tomcat本身不具备此能力,JBoss、WebLogic具备)找,如果有,则用旧的,否则创建新的,事务提交自动Close;
getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行如下设置:
如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
总之:
getCurrentSession () 使用当前的session
openSession() 重新建立一个新的session
在一个应用程序中,如果DAO 层使用Spring 的hibernate 模板,通过Spring 来控制session 的生命周期,则首选getCurrentSession ()。
源码下载
代码如下:
servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { User u1 = new User(); u1.setName("lilei"); u1.setAge(17); User u2 = new User(); u2.setName("hanmeimei"); u2.setAge(16); new UserService().save(u1, u2); }service
package com.hib.service; import com.hib.dao.UserDao; import com.hib.domain.User; public class UserService { public void save(User u1, User u2) { UserDao userDao = new UserDao(); userDao.save1(u1); int a = 10 / 0; userDao.save2(u2); } }dao
package com.hib.dao; import org.hibernate.Session; import org.hibernate.Transaction; import com.hib.domain.User; import com.hib.utils.HibernateUtils; public class UserDao { public void save1(User u1) { Session session = HibernateUtils.getSession(); Transaction tx = session.beginTransaction(); session.save(u1); tx.commit(); session.close(); } public void save2(User u2) { Session session = HibernateUtils.getSession(); Transaction tx = session.beginTransaction(); session.save(u2); tx.commit(); session.close(); } }在service层,如果抛出了异常,第一个user能够保存,第二个user不会被保存。这不符合业务要求。
那么在service层开启事务,代码修改如下:
hibernate.cfg.xml添加一个配置项
<!-- 开启绑定本地session --> <property name="hibernate.current_session_context_class">thread</property>
HibernateUtils添加方法
/** * 业务层开事务,就用这个 * @return */ public static Session getCurrentSession() { // 从ThreadLocal类中获取到session对象 return FACTORY.getCurrentSession(); }
service
package com.hib.service; import org.hibernate.Session; import org.hibernate.Transaction; import com.hib.dao.UserDao; import com.hib.domain.User; import com.hib.utils.HibernateUtils; public class UserService { public void save(User u1, User u2) { UserDao userDao = new UserDao(); // 获取session Session session = HibernateUtils.getCurrentSession(); // 开启事务 Transaction tx = session.beginTransaction(); try { userDao.save1(u1); int a = 10 / 0; userDao.save2(u2); // 提交事务 tx.commit(); } catch (Exception e) { e.printStackTrace(); // 出现问题回滚事务 tx.rollback(); } finally { // 以前,要手动释放资源。现在,session不用关闭,线程结束了,自动关闭 } } }dao
package com.hib.dao; import org.hibernate.Session; import com.hib.domain.User; import com.hib.utils.HibernateUtils; public class UserDao { public void save1(User u1) { Session session = HibernateUtils.getCurrentSession(); session.save(u1); } public void save2(User u2) { Session session = HibernateUtils.getCurrentSession(); session.save(u2); } }
Hibernate openSession() 和 getCurrentSession的区别
getHiberanteTemplate 、getCurrentSession和OpenSession
采用getCurrentSession()创建的Session会绑定到当前的线程中去、而采用OpenSession()则不会。
采用getCurrentSession()创建的Session在commit或rollback后会自动关闭,采用OpenSession()必须手动关闭。
采用getCurrentSession()需要在Hibernate.cfg.xml配置文件中加入如下配置:
如果是本地事物,及JDBC一个数据库:
<propety name=”Hibernate.current_session_context_class”>thread</propety>
如果是全局事物,及jta事物、多个数据库资源或事物资源:
<propety name=”Hibernate.current_session_context_class”>jta</propety>
使用spring的getHiberanteTemplate 就不需要考虑事务管理和session关闭的问题:
openSession创建session时autoCloseSessionEnabled参数为false,即在事物结束后不会自动关闭session,需要手动关闭,如果不关闭将导致session关联的数据库连接无法释放,最后资源耗尽而使程序当掉。
getCurrentSession创建session时autoCloseSessionEnabled,flushBeforeCompletionEnabled都为true,并且session会同sessionFactory组成一个map以sessionFactory为主键绑定到当前线程。
getCurrentSession():从上下文(配置文件current_session_context_class: thread 使用Connection自动管理;jta(java transaction api) 由Application Server提供的分布式事务管理,Tomcat本身不具备此能力,JBoss、WebLogic具备)找,如果有,则用旧的,否则创建新的,事务提交自动Close;
getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行如下设置:
如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
总之:
getCurrentSession () 使用当前的session
openSession() 重新建立一个新的session
在一个应用程序中,如果DAO 层使用Spring 的hibernate 模板,通过Spring 来控制session 的生命周期,则首选getCurrentSession ()。
源码下载
相关文章推荐
- 重拾Hibernate框架——实体类、主键生成策略、session绑定本地线程
- Hibernate的学习之路十六(绑定本地session)
- hibernate 本地线程绑定session
- Hibernate的学习之路十六(绑定本地session)
- Hibernate的学习之路十六(绑定本地session)
- Hibernate的学习之路十六(绑定本地session)
- [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定
- Hibernate中Session与本地线程绑定
- Hibernate中Session与本地线程作绑定
- Hibernate的学习之路十六(绑定本地session)
- Hibernate的学习之路十六(绑定本地session)
- Hibernate中Session与本地线程绑定
- Hibernate的学习之路十六(绑定本地session)
- hibernate 管理Session:Session 对象的生命周期与本地线程绑定
- Hibernate的学习之路十六(绑定本地session)
- Hibernate的学习之路十六(绑定本地session)
- Hibernate的学习之路十六(绑定本地session)
- hibernate中session与本地线程绑定
- Hibernate的学习之路十六(绑定本地session)
- hibernate事务代码规范和session与本地线程绑定