我正在使用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不能很好用它?有人知道更多吗?
答案 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接口不会暴露给上下文,因此数据源不会关闭。