分享

在Spring+hebernate中 Cannot get a connection, pool error Timeout waiting for idle object异常的解决办法

 昵称15242507 2014-04-14

在Spring+hebernate中 Cannot get a connection, pool error Timeout waiting for idle object异常的解决办法

   最近写了个留言板,tomcat+Spring+hibernate+MyEclipse

   使用jdbc连接数据库所有功能都没问题,发布到tomcat中也没问题,可是如果使用tomcat的数据源,来连接数据库,开始很正常,但是刷新几次就会出现这个异常……2008-04-26 22:35:40,812 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: null

 2008-04-26 22:35:40,812 ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object

 2008-04-26 22:35:40,812 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: null

 2008-04-26 22:35:40,812 ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object

 2008-04-26 22:35:40,812 ERROR [com.dao.MessageDAO] - find all failed

 org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: Cannot open connection; uncategorized SQLException for SQL [???]; SQL state [null]; error code [0]; Cannot get a connection, pool error Timeout waiting for idle object; nested exception is org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object

Caused by:

org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object

    at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:104)

    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)

    at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection (LocalDataSourceConnectionProvider.java:81)

    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:417)

    at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)

    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:105)

    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1561)

    at org.hibernate.loader.Loader.doQuery(Loader.java:661)

    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)

    at org.hibernate.loader.Loader.doList(Loader.java:2145)

    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2029)

    at org.hibernate.loader.Loader.list(Loader.java:2024)

    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:375)

    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:308)

    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:153)

    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1106)

    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)

    at org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:849)

    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)

    at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:840)

    at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:832)

  ……………………

开始弄了半天也不知道怎么回事,后来发现是我自己写的分页代码有问题……原来的代码如下:

/**

     * 自定义的,用属性模糊查询

     *

     * */

    public List find(String propertyName, Object value) {

        log.debug("finding Message instance with property: " + propertyName

              + ", value: " + value);

        try {

           String queryString = "from Message as model where model."

                                   + propertyName + " like "+value+" order by model.time desc";          

           return getHibernateTemplate().find(queryString);

        } catch (RuntimeException re) {

           log.error("find by property name failed", re);

           throw re;

        }

      }

   

   

    /**

     *

     * 自定义的方法,获取指定页的数据

     *

     * */

    public List gotoPage(int page,int pageSize){

       

        int totItem = this.findAll().size();//记录总条数

        int pageNum = totItem / pageSize +1;//总页数

        int begin = 0;//当前起始记录数

       

        begin=page*pageSize-pageSize+1; //计算当前起始位置

       

        Session s =this.getSession();

        String hql = "from Message message order by message.time desc";

        Query q =s.createQuery(hql);

        q.setFirstResult(begin);

        q.setMaxResults(pageSize);      

        return q.list();

    }

在这句中: Session s =this.getSession();

        String hql = "from Message message order by message.time desc";

        Query q =s.createQuery(hql);

   查询数据时,Spring并不能够自动管理连接,也就是说,在使用中这几句代码重视不段的获取数据库的连接,每调用一次就申请一个连接……直到 tomcat连接池中的连接耗尽……所以就再也申请不到连接了……出现了这个异常,解决办法是使用事务来管理这段代码,让Spring自动管理这段代码中申请的连接。我使用了Spring AOP自动事务代理……配置文件如下……

<!-- 来自JNDI的tomcat数据源,有连接池。但是用起来怎么就释放不了连接呢?程序只知道申请,不知道释放! -->

    <bean id="JndiDataSource"

        class="org.springframework.jndi.JndiObjectFactoryBean">

        <property name="jndiName">

            <value>java:comp/env/SqlServer</value>

        </property>

        <property name="resourceRef">

            <value>true</value>

        </property>

    </bean>

    <!-- hibernate的会话工厂 -->

    <bean id="sessionFactory"

        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">

            <ref bean="JndiDataSource"></ref>

        </property>

        <property name="hibernateProperties">

            <props>

                <prop key="hibernate.dialect">

                    org.hibernate.dialect.SQLServerDialect

                </prop>

                <!-- 显示SQL,为了方便测试 -->

                <prop key="hibernate.show_sql">true</prop>

            </props>

        </property>

        <property name="mappingResources">

            <list><!-- 映射文件 -->

                <value>./Message.hbm.xml</value>

                <value>./Setting.hbm.xml</value>

                <value>./Admin.hbm.xml</value>

            </list>

        </property>

    </bean>

    <!-- 事务管理器 -->

    <bean id="transactionManger"

        class="org.springframework.orm.hibernate3.HibernateTransactionManager">

        <property name="sessionFactory">

            <ref bean="sessionFactory" />

        </property>

    </bean>

    <!--   配置事务拦截器-->

    <bean id="transactionInterceptor"

        class="org.springframework.transaction.interceptor.TransactionInterceptor">

        <property name="transactionManager">

            <ref bean="transactionManger" />

        </property>

        <!--   下面定义事务传播属性-->

        <property name="transactionAttributes">

            <props>

                <prop key="find*">PROPAGATION_REQUIRED</prop>

                <prop key="delete*">PROPAGATION_REQUIRED</prop>

                <prop key="save*">PROPAGATION_REQUIRED</prop>

                <prop key="merge*">PROPAGATION_REQUIRED</prop>

                <prop key="attach*">PROPAGATION_REQUIRED</prop>               

                <prop key="gotoPage">PROPAGATION_REQUIRED</prop>

            </props>

        </property>

    </bean>

    <!--  自动代理 -->

    <bean id="autoBeanNameProxyCreator"

        class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

        <property name="beanNames">

            <list>

                <value>*DAO</value>              

                <value>gotoPage</value>

                <value>find</value>

            </list>

        </property>

        <property name="interceptorNames">

            <list>

                <idref local="transactionInterceptor" />

            </list>

        </property>

       

        <!--  这里的配置是必须的,否则无法完成代理的类型转化

        这是使用CGLIB来生成代理

        -->

        <property name="proxyTargetClass" value="true"/>

    </bean>

    <bean id="MessageDAO" class="com.dao.MessageDAO">

        <property name="sessionFactory">

            <ref bean="sessionFactory"></ref>

        </property>

    </bean>

    <bean id="SettingDAO" class="com.dao.SettingDAO">

        <property name="sessionFactory">

            <ref bean="sessionFactory"></ref>

        </property>

    </bean>

    <bean id="AdminDAO" class="com.dao.AdminDAO">

        <property name="sessionFactory">

            <ref bean="sessionFactory"></ref>

        </property>

    </bean>

</beans>

 

OK,问题成功解决!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多