(八) 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的声明式事务一起使用。

 

 

代码在下章

 

posted @ 2017-05-13 19:46  shyroke、  阅读(563)  评论(0编辑  收藏  举报
作者:shyroke 博客地址:http://www.cnblogs.com/shyroke/ 转载注明来源~