【问题标题】:Tomcat 5.5 DBCP Connection Pool DataSource is closedTomcat 5.5 DBCP 连接池数据源已关闭
【发布时间】:2014-08-02 20:11:24
【问题描述】:

我正在使用 Spring Data JPA 和 Hibernate 开发一个 Spring Web 应用程序,在 Tomcat 5.5 上运行。 Tomcat 使用 DBCP 进行连接池。

池是这样定义的:

<Resource auth="Container" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
        factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
        logAbandoned="true" maxActive="100" maxIdle="30" maxWait="10000"
        minIdle="3" name="..." password="..." removeAbandoned="true"
        type="javax.sql.DataSource"
        url="..." username="..." validationQuery="select 1" />

在 Java 端,我通过 JNDI 获取数据源,Spring 将对象作为单例进行管理,它仅用于创建 EntityManagerFactory。

现在我的问题。当我第一次在新启动的 Tomcat 上部署应用程序时,一切正常。如果我第一次热部署该应用程序,一切仍然正常。但是,如果我第二次进行热部署,则会出现以下异常:

java.sql.SQLException: Data source is closed
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1362)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)

感谢任何想法,谢谢!

更新:我在 Tomcat 7.0.12 上进行了尝试,它在我的机器上并有同样的问题。我已经从 commons-dbcp 切换到 Tomcat JDBC 连接池,并且问题在 Tomcat 5.5 和 Tomcat 7 上都消失了。现在在我看来,commons-dbcp 中存在错误,或者 Spring 不适合它?有人知道更多吗?

【问题讨论】:

  • Tomcat 5.5?你确定吗? Apache 网站列出了 6、7 和 8。您的服务器有多少年了?对于 Java 1.4、Servlet 2.4 和 JSP 2.0?真的吗?
  • 嗨,Elliott,是的,我确信这里的更新过程有点慢...... :-) 我们已经在 J​​ava 1.6 上!
  • 检查您使用的 spring 和 hibernate 版本的要求。那个 Tomcat 真的很老了。并且可能切换到不同的CP。
  • 我们也遇到过很多问题。 UCP 似乎是唯一正确验证 oracle 连接的连接池:(
  • 所以我想在我们升级之前我将不得不忍受这种情况。不应该再这么久了,我希望。谢谢大家。

标签: java spring hibernate tomcat apache-commons-dbcp


【解决方案1】:

首先,使用受支持的 Tomcat 版本。 Commons DBCP 已死/过时。您应该使用 Tomca JDBC Pool 或 Commons DBCP2。

【讨论】:

    【解决方案2】:

    为数据源 Spring bean 定义一个空的 destroyMethod。如果没有定义destroyMethod,则在取消部署Spring 调用close()shutdown() 上的bean。 看到这个Why does Datasources close on Tomcat 7 undeploy with Spring Boot

    data.xml

    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean" destroy-method="">
    

    或在@Bean注解中

    @Bean(name = "dataSource", destroyMethod = "")
    public DataSource getDataSource() {...}
    

    【讨论】:

      【解决方案3】:

      在新版本的 Tomcat 中,数据源实现了 AutoClosable。默认情况下,Spring 检测到该接口并在取消部署时调用数据源上的关闭。在一些有漏洞的 Spring 版本(4.1.x 和

      另一种避免这种情况的方法是包装数据源。

          @Bean
      public DataSource getJndiDataSource() {
          try {
              JndiTemplate jndiTemplate = new JndiTemplate();
              DataSource ds = (DataSource) jndiTemplate.lookup("java:comp/env/"+JNDI_DATASOURCE);
              return new DelegatingDataSource(ds);
          } catch(NamingException e){
              LOG.error("Could not find JNDI data source (java:comp/env/):"+JNDI_DATASOURCE, e);
              return null;
          }
      }
      

      通过使用 DelegatingDataSource 包装数据源,AutoClosable 接口不会暴露给上下文,因此数据源不会关闭。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-25
        • 1970-01-01
        • 2020-08-22
        • 2013-01-02
        • 2019-03-03
        • 1970-01-01
        相关资源
        最近更新 更多