Tomcat 5.5 DBCP连接池DataSource已关闭

时间:2014-06-12 13:18:46

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

我正在使用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将对象管理为singelton,它只用于创建 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中有一个bug或者Spring不能很好用它?有人知道更多吗?

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

为数据源Spring bean定义一个空的destroyMethod。如果没有定义destroyMethod,则取消部署Spring会在bean上调用close()shutdown()。 请参阅此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() {...}

答案 2 :(得分:0)

在新版本的Tomcat中,数据源实现了AutoClosable。默认情况下,Spring检测到该接口并在取消部署时调用数据源上的close。在某些版本的bug(4.1.x和<4.2.2)中,如果检测到AutoClosable接口,则会忽略destroyMethod。

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

Array

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