我们在多线程环境中使用Spring Batch。我们使用连接池从数据库获取连接。但是在尝试执行proc时,很少有线程抛出异常。数据库连接设置,maxthreads = 120。
我们使用Oracle JDK 7,Spring 4,ojdbc6.jar从Windows 2008计算机运行批处理。
请您告诉我可能的原因和缓解措施?
<bean id="pooledDataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="defaultAutoCommit" value="false" />
<property name="defaultTransactionIsolation" value="2" />
<property name="maxTotal" value="#{${maxThreads}*5}" />
<property name="maxIdle" value="10" />
<property name="poolPreparedStatements" value="true" />
<property name="maxOpenPreparedStatements" value="100" />
<property name="minEvictableIdleTimeMillis" value="-1" />
<property name="removeAbandonedTimeout" value="900" />
<property name="removeAbandonedOnMaintenance" value="true" />
<property name="testOnBorrow" value="true" />
<property name="logAbandoned" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="20000"/>
</bean>
异常
2018-01-09 06:57:07.334 ERROR o.s.batch.core.step.AbstractStep - Encountered an error executing step aStep in job cycleJob
com.test.system.exception.BackEndSystemException: error
at com.test.system.batch.CycleDAO.loadStatus(CycleDAO.java:759) ~[xxxxxxx-batch-1.0-SNAPSHOT.jar:na]
at com.test.system.batch.CycleItemWriter.write(CycleItemWriter.java:78) ~[xxxxxxx-batch-1.0-SNAPSHOT.jar:na]
at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at com.sun.proxy.$Proxy20.write(Unknown Source) ~[na:na]
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:151) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:274) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:199) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368) ~[spring-batch-infrastructure-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) ~[spring-batch-infrastructure-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198) ~[spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:139) [spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:136) [spring-batch-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
at org.springframework.core.task.SimpleAsyncTaskExecutor$ConcurrencyThrottlingRunnable.run(SimpleAsyncTaskExecutor.java:251) [spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
Caused by: java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:458) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at org.apache.commons.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:39) ~[commons-dbcp2-2.1.1.jar:2.1.1]
at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:256) ~[commons-dbcp2-2.1.1.jar:2.1.1]
at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868) ~[commons-pool2-2.4.2.jar:2.4.2]
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435) ~[commons-pool2-2.4.2.jar:2.4.2]
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) ~[commons-pool2-2.4.2.jar:2.4.2]
at org.apache.commons.dbcp2.PoolingDataSource.getConnection(PoolingDataSource.java:134) ~[commons-dbcp2-2.1.1.jar:2.1.1]
at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1533) ~[commons-dbcp2-2.1.1.jar:2.1.1]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:104) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:225) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at com.sun.proxy.$Proxy31.prepareCall(Unknown Source) ~[na:na]
at com.test.system.batch.CycleDAO.loadStatus(CycleDAO.java:745) ~[xxxxxxx-batch-1.0-SNAPSHOT.jar:na]
... 32 common frames omitted
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:392) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:434) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:687) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:343) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1102) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:320) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
... 47 common frames omitted
Caused by: java.net.BindException: Address already in use: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.7.0_79]
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) ~[na:1.7.0_79]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) ~[na:1.7.0_79]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) ~[na:1.7.0_79]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) ~[na:1.7.0_79]
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.7.0_79]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.7.0_79]
at java.net.Socket.connect(Socket.java:579) ~[na:1.7.0_79]
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:150) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.net.nt.ConnOption.connect(ConnOption.java:133) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:370) ~[ojdbc6-11.2.0.jar:11.2.0.3.0]
... 52 common frames omitted
答案 0 :(得分:0)
看到我们看不到的唯一属性值是URL,用户和密码以及maxThreads,我不确定如何添加这些值会有所帮助。
此处的问题是连接池正在尝试向其添加新连接,并且Oracle拒绝创建它们,因此您的池设置为使用比Oracle愿意发布的更多连接。
要解决您的问题,我实际上会将池中的连接数减少到Oracle可以处理的内容,并将池上的maxWaitMillis设置为适当的值(默认值是永远等待您可能想要或可能不想要的)。
这将允许Spring Batch线程在那里等待连接池的连接,而不是在连接池尝试分配连接时出现故障。
换句话说,尝试连接池的连接数少于Oracle允许的最大连接数,并且少于您运行的线程数。
您当前正在将最大总连接数设置为线程数的5倍。如果您接近此使用级别,则可能会出现连接泄漏。