Hibernate 使用 proxool 连接池 隔一段时间自动断开连接,郁闷死了,请求大家帮忙
数据持久层:Hibernate 3.1
连接池:proxool 0.8.3
症状描述: 正常操作没有问题,如果过上一段时间不操作,比较机器闲置半小时(TOMCAT容器正常工作)左右,当你再次操作的时候,报500错误,说connection.close()方法已经被执行。错误详情如下:
- Java code
ERROR[http-8080-Processor23](StandardWrapperValve.java:253)-Servlet.service() for servlet action threw exceptioncom.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state. at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:981) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927) at com.mysql.jdbc.ConnectionImpl.getMutex.......
--------------------
下面是几个主要的配置文件,贴出来:
hibernate.cfg.xml
- Java code
<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="show_sql">true</property> <!-- proxool connection pool config --> <property name="proxool.pool_alias">dbpool</property> <property name="proxool.xml">proxool_conf.xml</property> <property name="connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</property> <mapping resource="com/erp/puaite/main/TbAdmin.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbProduct.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbSuppliers.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbMonthlyBuylistSummaryDetil.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbMonthlyBuylistSummary.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbNewaddPlannedBuylistDetil.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbNewaddPlannedBuylist.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbProducingPlannedBuylistDetil.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbProducingPlannedBuylist.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbReceiveGoods.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbSendmoneyList.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbStockMonthlyReportDetil.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbStockMonthlyReport.hbm.xml" /> <mapping resource="com/erp/puaite/main/TbSupplierGivingPrice.hbm.xml" /></session-factory></hibernate-configuration>
proxool_conf.xml
- Java code
<?xml version="1.0" encoding="UTF-8"?><something-else-entirely> <proxool> <alias>dbpool</alias> <driver-url>jdbc:mysql://localhost:3306/db_puaite?useUnicode=true&characterEncoding=utf-8</driver-url> <driver-class>org.gjt.mm.mysql.Driver</driver-class> <driver-properties> <property name="user" value="root" /> <property name="password" value="186899" /> </driver-properties> <house-keeping-sleep-time>90000</house-keeping-sleep-time> <maximum-active-time>60000</maximum-active-time> <maximum-new-connections>100</maximum-new-connections> <prototype-count>5</prototype-count> <maximum-connection-count>50</maximum-connection-count> <minimum-connection-count>10</minimum-connection-count> </proxool></something-else-entirely>
web.xml
- Java code
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/html/*</url-pattern> </servlet-mapping> <filter> <filter-name>myfilter</filter-name> <filter-class>com.erp.puaite.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>myfilter</filter-name> <url-pattern>/html/admin/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>
获取Session的工具类
- Java code
package sessionFactory;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.cfg.Configuration;public class HibernateSessionFactory { private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration(); private static org.hibernate.SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; static { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err .println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } private HibernateSessionFactory() { } public static Session getSession() throws HibernateException { Session 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(configFile); 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 = (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; }}
备注:我发现闲置一段时间之后,proxool在控制台自动打印出以下几句话:
WARN[HouseKeeper](HouseKeeper.java:142)-#0002 was active for 152813 milliseconds and has been removed automaticaly. The Thread responsible was named 'http-8080-Processor24'.
WARN[HouseKeeper](HouseKeeper.java:142)-#0014 was active for 85469 milliseconds and has been removed automaticaly. The Thread responsible was named 'http-8080-Processor23'.
辛苦大家啦!
[解决办法]
proxool配置文件中的参数maximum-active-time
<maximum-active-time>60000</maximum-active-time>
其含义是一个线程持有一个连接的最长时间,而不管这个连接是否处于 active 状态, 并且如果线程的持有时间超过这个时间的之后会自动清除掉这个连接.
60000=5分钟,一般是不够的,请加大这个值到最大的可能空闲时间之上。
[解决办法]
学习了
[解决办法]
proxool配置文件中的参数maximum-active-time默认时间是5分钟,60000=1分钟吧!应该是以毫秒为最小单位的
[解决办法]
[解决办法]
学习了
[解决办法]
不错 !!
[解决办法]
=======================
proxool配置文件中的参数maximum-active-time
<maximum-active-time>60000 </maximum-active-time>
其含义是一个线程持有一个连接的最长时间,而不管这个连接是否处于 active 状态, 并且如果线程的持有时间超过这个时间的之后会自动清除掉这个连接.
60000=5分钟,一般是不够的,请加大这个值到最大的可能空闲时间之上。
===================================
2楼同志我有个问题,如果我的空闲时间还是超过了maximum-active-time所规定的时间,那么我就只能重起web服务了吗?
[解决办法]
这样好像解决不了问题吧