java Tomcat 5.5 DBCP连接池数据源已关闭
我正在用Spring数据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将对象作为Singleton进行管理,它将只用于创建 整个管理工厂
现在是我的问题。当我第一次在刚启动的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对它不友好?有人知道更多吗
# 1 楼答案
为数据源Springbean定义一个空方法。在取消部署时,如果没有定义destroyMethod,Spring会在bean上调用
close()
或shutdown()
。 看这个Why does Datasources close on Tomcat 7 undeploy with Spring Boot在
data.xml
或者在
@Bean
注释中# 2 楼答案
首先,使用受支持的Tomcat版本。Commons DBCP已过时。您应该使用Tomca JDBC池或Commons DBCP2
# 3 楼答案
在新版Tomcat中,数据源实现了自动关闭。默认情况下,Spring会检测该接口,并在取消部署时调用数据源上的close。在一些有缺陷的Spring版本(4.1.x和<;4.2.2)中,如果检测到自动关闭接口,则会忽略destroyMethod
另一种避免这种情况的方法是包装数据源
通过使用DelegatingDataSource包装数据源,AutoClosable接口不会暴露于上下文,因此数据源不会关闭