我有一个连接到SQL Server 2012下的数据库的java spring应用程序。 这是我正在使用的属性和数据源:
-datasource.initialSize=34
-datasource.minIdle=89
-datasource.maxIdle=233
-datasource.maxActive=377
-datasource.maxWait=50000
-datasource.abandonWhenPercentageFull=50
-datasource.jmxEnabled=true
-datasource.removeAbandoned=true
-datasource.removeAbandonedTimeout=120
-datasource.logAbandoned=true
-datasource.testOnBorrow=true
-datasource.timeBetweenEvictionRunsMillis=60000
-datasource.minEvictableIdleTimeMillis=80000
-datasource.validationInterval=40000
和spring管理的数据源:
<bean id="myDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"
p:driverClassName="${datasource.driverClass}"
p:url="${datasource.url}"
p:username="${datasource.user}"
p:password="${datasource.pass}"
p:maxWait="${datasource.maxWait}"
p:minIdle="${datasource.minIdle}"
p:maxIdle="${datasource.maxIdle}"
p:maxActive="${datasource.maxActive}"
p:jmxEnabled="${datasource.jmxEnabled}"
p:removeAbandoned="${datasource.removeAbandoned}"
p:removeAbandonedTimeout="${datasource.removeAbandonedTimeout}"
p:logAbandoned="${datasource.logAbandoned}"
p:testOnBorrow="${datasource.testOnBorrow}"
p:timeBetweenEvictionRunsMillis="${datasource.timeBetweenEvictionRunsMillis}"
p:minEvictableIdleTimeMillis="${datasource.minEvictableIdleTimeMillis}"
p:validationInterval="${datasource.validationInterval}"
p:abandonWhenPercentageFull="${datasource.abandonWhenPercentageFull}"
p:validationQuery="SELECT 1"
p:jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.ConnectionState"
/>
我有一个发送大量JMS消息的进程。我在不同时间收到相同的错误消息,说我的JMS侦听器中的连接已关闭。知道为什么它会关闭连接吗?
org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Unable to commit against JDBC Connection
at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:585)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.spectrags.fundhive.interceptor.PerfInterceptor.invoke(PerfInterceptor.java:34)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.spectrags.fundhive.business.api.messaging.WorkflowJmsListener$$EnhancerBySpringCGLIB$$704b2c20.onMessage(<generated>)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:746)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:684)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039)
at java.lang.Thread.run(Unknown Source) Caused by: org.hibernate.TransactionException: Unable to commit against JDBC Connection
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:86)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:581)
... 21 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.checkClosed(SQLServerConnection.java:388)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.commit(SQLServerConnection.java:1936)
at sun.reflect.GeneratedMethodAccessor150.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:152)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:70)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:70)
at org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer.invoke(ResetAbandonedTimer.java:62)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
at org.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:40)
at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81)
at com.sun.proxy.$Proxy21.commit(Unknown Source)
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:80)
... 24 more
编辑2016年2月25日:这是我已经实施的,但它仍然无法运作:
public class ConnectionJDBCInterceptor extends JdbcInterceptor {
protected static Logger log = Logger.getLogger(ConnectionJDBCInterceptor.class.getName());
@Override
public void reset(final ConnectionPool pool, final PooledConnection pooledConnection) {
try {
if (pooledConnection.getConnection().isClosed()) {
ConnectionJDBCInterceptor.log.info("Closed connection in the pool is being reconnected");
pooledConnection.reconnect();
}
} catch (final SQLException e) {
ConnectionJDBCInterceptor.log.error(e, "Error in JDBC Interceptor", e);
}
}
}
答案 0 :(得分:2)
我有类似的问题。在IOException的情况下,sqlserver jdbc驱动程序将连接标记为已关闭,但池未检测到此情况。因此,连接在池中返回,但不可用。 解决这个问题的方法是为tomcatjdbc编写一个新的JDBCInterceptor。拦截器必须在调用close时,在底层连接上调用“isClosed”。如果底层连接已关闭,则拦截器必须将PooledConnection标记为已丢弃。 然后配置您的池以使用此拦截器。
答案 1 :(得分:0)
如果您不使用Tomcat JDBC池,则可以将其从项目中排除,从而解决了重新连接的问题。
对于gradle:
configurations.all {
exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc'
}
答案 2 :(得分:0)