(八) Hibernate中的Session以及事务
- HibernateUtil.getSessionFactory().getCurrentSession() 和HibernateUtil.getSession() 的区别:
1.异:getCurrentSession() 创建的线程会在事务回滚或事物提交后自动关闭,而getSession需要手动关闭。
2.同:都是从本地线程中取得session
- 每次使用sessionFactory.openSession()获得的session都不一样。
案例一:
- UserDao.java
package dao; import org.hibernate.Session; import org.hibernate.Transaction; import bean.User; import util.HibernateUtil; public class UserDao { public static void save1() { Session session = null; Transaction tran = null; User user = new User(); user.setUserid(9); user.setUsername("user7"); user.setPassword("123"); try { session = HibernateUtil.getSessionFactory().openSession(); tran = session.beginTransaction(); session.save(user); tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { if(session!=null){ session.close(); } } } public static void save2() { Session session = null; Transaction tran = null; User user = new User(); user.setUserid(9); user.setUsername("user7"); user.setPassword("123"); try { session = HibernateUtil.getSession(); System.out.println("userdao session=="+session.hashCode()); tran = session.beginTransaction(); session.save(user); tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { // HibernateUtil.closeSession(); } } public static void save3() { Session session = null; Transaction tran = null; User user = new User(); user.setUserid(9); user.setUsername("user7"); user.setPassword("123"); try { session = HibernateUtil.getSessionFactory().getCurrentSession(); System.out.println("userdao session=="+session.hashCode()); tran = session.beginTransaction(); session.save(user); tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { } } public static void save4(Session session) { Transaction tran = null; User user = new User(); user.setUserid(9); user.setUsername("user7"); user.setPassword("123"); try { System.out.println("userdao session=="+session.hashCode()); tran = session.beginTransaction(); session.save(user); tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { } } }
- RoleDao.java
package dao; import org.hibernate.Session; import org.hibernate.Transaction; import util.HibernateUtil; import bean.User; public class RoleDao { public static void save1() { Session session = null; Transaction tran = null; User user = new User(); user.setUserid(10); user.setUsername("user7"); user.setPassword("123"); try { session = HibernateUtil.getSessionFactory().openSession(); tran = session.beginTransaction(); session.save(user); int i=1/0; tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { if(session!=null){ session.close(); } } } public static void save2() { Session session = null; Transaction tran = null; User user = new User(); user.setUserid(10); user.setUsername("user7"); user.setPassword("123"); try { session = HibernateUtil.getSession(); System.out.println("rolesession=="+session.hashCode()); tran = session.beginTransaction(); session.save(user); int i=1/0; tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { HibernateUtil.closeSession(); } } public static void save3() { Session session = null; Transaction tran = null; User user = new User(); user.setUserid(10); user.setUsername("user7"); user.setPassword("123"); try { session = HibernateUtil.getSessionFactory().getCurrentSession(); System.out.println("roledao session=="+session.hashCode()); tran = session.beginTransaction(); session.save(user); int i=2/0; tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { } } public static void save4(Session session) { Transaction tran = null; User user = new User(); user.setUserid(10); user.setUsername("user7"); user.setPassword("123"); try { System.out.println("roledao session=="+session.hashCode()); tran = session.beginTransaction(); session.save(user); int i=2/0; tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { } } }
- Hibernate_Session.java
package action; import org.hibernate.Session; import org.hibernate.SessionFactory; import bean.Role; import dao.RoleDao; import dao.UserDao; import util.HibernateUtil; /** * Hibernate中的Session的事务管理 * * @author 半颗柠檬、 * */ public class Hibernate_Session { public static void main(String[] args) { // Hibernate_Session.testone(); // Hibernate_Session.testTwo(); // Hibernate_Session.testThree(); Hibernate_Session.testFour(); } private static void testone() { /** * 每次由sessionFactory。openSession()得到的session都不一样, */ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session1 = sessionFactory.openSession(); System.out.println(session1.hashCode()); Session session2 = sessionFactory.openSession(); System.out.println(session2.hashCode()); /* * UserDao和RoleDao中的save1方法的session都是通过sessionFactory.openSession()所得到, * 不是同一个session,也就是说两个方法不是公用一个事务 */ UserDao.save1(); RoleDao.save1(); } private static void testTwo() { /** * 由HibernateUtil.getSession()得到的是同一个session对象,查看HibernateUtil。 * getSession()可知getSession方法是从ThreadLocal中取得的。 */ Session session1 = HibernateUtil.getSession(); System.out.println(session1.hashCode()); Session session2 = HibernateUtil.getSession(); System.out.println(session2.hashCode()); /** * 虽然UserDao和RoleDao中是同一个session,但是两个方法却不是同一个事务,因为每一个方法里的tran.commit() * 方法都隐式调用了flush方法,这个方法 * 的主要作用是清理缓存,强制数据库与Hibernate缓存同步,以保证数据的一致性,然后再提交事务,UserDao.save2()方法 * 已经提交事务,等到RoleDao.save2()方法的时候, 事务已经是新的了。 */ UserDao.save2(); RoleDao.save2(); } /** * 使用getCurrentSession时, 在hibernate.cfg.xml中要配置 * * <property name="current_session_context_class">thread</property> * 这个配置的目的是把session交给ThreadLocal管理 * * getCurrentSession时,Session会自动关闭。不需要手工关闭。 */ private static void testThree() { /** * 使用getSessionFactory().getCurrentSession()得到的session是同一个线程上的同一个session * getSessionFactory(). * getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,如果手动关闭则会报错。 */ Session session1 = HibernateUtil.getSessionFactory() .getCurrentSession(); System.out.println(session1.hashCode()); Session session2 = HibernateUtil.getSessionFactory() .getCurrentSession(); System.out.println(session2.hashCode()); /** * 两个方法依然无法共享一个事务,值得注意的是这两个方法的session不是同一个session, * 原因在于getCurrentSession的session会在事务回滚或者提交之后自动关闭 * ,当UserDao.save3()成功提交之后session就关闭了,所以RoelDao的session是重新创建的 session */ UserDao.save3(); RoleDao.save3(); } private static void testFour() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); /** * UserDao和RoleDao的save4方法共享一个session * 但是依旧无法共享事务,因为session在UserDao.save4方法提交的时候已经被关闭了, * RoleDao.save4使用session就会报错,错误消息为“Session is closed!” */ UserDao.save4(session); RoleDao.save4(session); } }
- 总结: 在hibernate中很难控制事务,如果需要控制事务,一般都是和spring的声明式事务一起使用。
代码在下章