X0SHUAI 2009-12-29
hibernate中的Session关系到对数据库的增删查改等基本的数据存取操作.对Session进行有效的维护,就像是在jdbc编程中对JDBC collection的维护.
在struts+hibernate的方案中,常常利用过滤器(Filter)对session进行管理,以实现session在线程范围内的共享.为什么仅仅实现线程内的共享,是因为,不能把session用于多线程,否则会出现意外.在线程范围内实现sesion的共享.避免了session的频繁的创建和销毁.我看到有的程序中,在单个方法内,打开session,执行.关闭session.这显然没有在一次会话中有效的利用session
下面的方案是.通过建立一个过滤器,以实现对sesion的共享:
package com.cs_oj.filter; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Session; import org.hibernate.Transaction; import com.cs_oj.data.dao.HibernateSessionFactory; public class HibernateSessionFilter implements Filter { private static final Log log = LogFactory.getLog(HibernateSessionFilter.class); public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { log.debug("HibernateSessionFilter start"); Date date=new Date(); DateFormat df=new SimpleDateFormat("yyyy-MM-dd '时间--'HH:mm:ss"); System.out.println("----当前时间:"+df.format(date)+"----"); System.out.println("----------HibernateSessionFilter start-----------"); //利用HibernateSessionFactory, 得到当 前线程中的session对象..HibernateSessionFactory的代码利用了ThreadLocal模式..详见..HibernateSessionFactory Session session=HibernateSessionFactory.getSession(); log.info("HibernateSessionFilter begin transaction"); System.out.println("HibernateSessionFilter begin transaction"); Transaction tx=session.beginTransaction(); //开始事务 log.debug("HibernateSessionFilter begin doChain"); HttpServletResponse response=(HttpServletResponse)arg1; try{ chain.doFilter(arg0, arg1); log.debug("HibernateSessionFilter begin commit"); //没有异常,则提交 try{ System.out.println("HibernateSessionFilter begin commit"); tx.commit(); System.out.println("HibernateSessionFilter commit success"); } catch(Exception e){ System.out.println("HibernateSessionFilter commit failed"); System.out.println("HibernateSessionFilter begin rollback() "); try{ System.out.println("HibernateSessionFilter begin rollback() "); tx.rollback(); System.out.println("HibernateSessionFilter rollback() success "); }catch(RuntimeException ex){ System.out.println("HibernateSessionFilter rollback() failed"); } } }catch (Exception e) { e.printStackTrace(); System.out.println("chain.doFilter(arg0, arg1) exception accurs "); System.out.println("HibernateSessionFilter begin rollback() "); tx.rollback(); //出现异常,回滚 //response.sendRedirect("error.jsp"); } finally{ log.debug("HibernateSessionFilter end doChain"); System.out.println("HibernateSessionFilter begin close session"); HibernateSessionFactory.closeSession(); System.out.println("*********HibernateSessionFilter close session success*********"); log.debug("HibernateSessionFilter begin close session"); //System.out.println("session.isOpen()="+session.isOpen()); } } }
package com.cs_oj.filter; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Session; import org.hibernate.Transaction; import com.cs_oj.data.dao.HibernateSessionFactory; public class HibernateSessionFilter implements Filter { private static final Log log = LogFactory.getLog(HibernateSessionFilter.class); public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { log.debug("HibernateSessionFilter start"); Date date=new Date(); DateFormat df=new SimpleDateFormat("yyyy-MM-dd '时间--'HH:mm:ss"); System.out.println("----当前时间:"+df.format(date)+"----"); System.out.println("----------HibernateSessionFilter start-----------"); //利用HibernateSessionFactory, 得到当 前线程中的session对象..HibernateSessionFactory的代码利用了ThreadLocal模式..详见..HibernateSessionFactory Session session=HibernateSessionFactory.getSession(); log.info("HibernateSessionFilter begin transaction"); System.out.println("HibernateSessionFilter begin transaction"); Transaction tx=session.beginTransaction(); //开始事务 log.debug("HibernateSessionFilter begin doChain"); HttpServletResponse response=(HttpServletResponse)arg1; try{ chain.doFilter(arg0, arg1); log.debug("HibernateSessionFilter begin commit"); //没有异常,则提交 try{ System.out.println("HibernateSessionFilter begin commit"); tx.commit(); System.out.println("HibernateSessionFilter commit success"); } catch(Exception e){ System.out.println("HibernateSessionFilter commit failed"); System.out.println("HibernateSessionFilter begin rollback() "); try{ System.out.println("HibernateSessionFilter begin rollback() "); tx.rollback(); System.out.println("HibernateSessionFilter rollback() success "); }catch(RuntimeException ex){ System.out.println("HibernateSessionFilter rollback() failed"); } } }catch (Exception e) { e.printStackTrace(); System.out.println("chain.doFilter(arg0, arg1) exception accurs "); System.out.println("HibernateSessionFilter begin rollback() "); tx.rollback(); //出现异常,回滚 //response.sendRedirect("error.jsp"); } finally{ log.debug("HibernateSessionFilter end doChain"); System.out.println("HibernateSessionFilter begin close session"); HibernateSessionFactory.closeSession(); System.out.println("*********HibernateSessionFilter close session success*********"); log.debug("HibernateSessionFilter begin close session"); //System.out.println("session.isOpen()="+session.isOpen()); } } }
在web.xml文件中对上面的过滤器进行配置.
package com.cs_oj.data.dao; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; public class HibernateSessionFactory { /** * Location of hibernate.cfg.xml file. * Location should be on the classpath as Hibernate uses * #resourceAsStream style lookup for its configuration file. * The default classpath location of the hibernate config file is * in the default package. Use #setConfigFile() to update * the location of the configuration file for the current session. */ private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration().configure(); private static org.hibernate.SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; private HibernateSessionFactory() { } /** * Returns the ThreadLocal Session instance. Lazy initialize * the <code>SessionFactory</code> if needed. * * @return Session * @throws HibernateException */ public static Session getSession() throws HibernateException { Session session = threadLocal.get(); if (session == null || !session.isOpen()) { if (sessionFactory == null) { rebuildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } return session; } /** * Rebuild hibernate session factory * */ public static void rebuildSessionFactory() { try { //configuration.configure(); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err .println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } /** * Close the single hibernate session instance. * * @throws HibernateException */ public static void closeSession() throws HibernateException { Session session = threadLocal.get(); threadLocal.set(null); if (session != null) { session.close(); } } /** * return session factory * */ public static org.hibernate.SessionFactory getSessionFactory() { return sessionFactory; } /** * return session factory * * session factory will be rebuilded in the next call */ public static void setConfigFile(String configFile) { HibernateSessionFactory.configFile = configFile; sessionFactory = null; } /** * return hibernate configuration * */ public static Configuration getConfiguration() { return configuration; } }