我一直在尝试将ojdbc代码从ojdbc14-10.2.0.1.0升级到ojdbc6-11.1.0.7.0。我们一直使用OracleConnectionCacheImpl进行数据源连接,然后使用OracleDataSource转移到通用连接池。以下是我们目前在Spring中配置它的方式:
<bean id="myDatasource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource">
<property name="URL" value="@JDBC_URL@"/>
<property name="user" value="@JDBC_USERNAME@"/>
<property name="password" value="@JDBC_PASSWORD@"/>
<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="connectionPoolName" value="MFR_RTE_POOL"/>
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="100"/>
<property name="validateConnectionOnBorrow" value="true" />
<property name="connectionWaitTimeout" value="30"/>
<property name="connectionHarvestMaxCount" value="25"/>
<property name="connectionHarvestTriggerCount" value="5"/>
<property name="maxStatements" value="100"/>
</bean>
在没有关闭连接错误的情况下运行它需要一些时间,但现在我遇到了内存管理问题。我已经针对我使用ThreadPool的应用程序运行jconsole。此应用程序使用线程池并使用ThreadPoolExecutors根据从文件传递的数据创建费用请求。一个文件可以有数十万个费用请求。我的问题是Heap中的长期记忆正在填满并且不会释放对象。在我设置的性能测试中,垃圾收集中的长期记忆大约在20-25分钟内完成,并且永远不会释放。该应用程序最终达到了GC Limit Exceeded Exception并停止运行。
当我使用旧的OracleConnectionCacheImpl类运行相同的测试时,它运行没有问题。假设线程池和所有附带的代码都是使用旧版本的Spring(1.2.6)和旧的ojdbc驱动程序编写的,但OracleConnectionCacheImpl与Universal Connection Pooling的工作原理有何不同?如果我想要容纳最新版本的Oracle JDBC驱动程序代码,我是否正在考虑重写我的域模型。我尝试过OracleDataSource连接,并且在同时处理多个文件后,它与NullPointerExceptions失败了。然后我去了UCP(在这个论坛的另一个帖子的建议),除了一个应用程序之外的所有工作都很好。此时我正在试图弄清楚是否可以为我的数据源进一步优化Spring配置bean,还是我需要开始考虑升级代码库。如前所述,此代码与旧的ojdbc类运行良好,但我在尝试实现UCP的每一步都遇到了问题。我开始怀疑它是否值得升级。
答案 0 :(得分:6)
这个问题困扰了我好几个月,我希望我想出的东西可以帮助其他人:
我终于找到了解决问题的方法。而不是使用OracleDataSource作为连接工厂:
<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
我建议尝试使用OracleConnectionPoolDataSource:
<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleConnectionPoolDataSource"/>
OracleConnectionPoolDataSource扩展了OracleDataSource,似乎在需要多个资源打开多个连接的应用程序中做得更好。在我的情况下,我有一个需要处理多个批处理文件的应用程序。相同的SQL代码反复运行,但应用程序需要为每个新文件建立新连接。在这些情况下,OracleDataSource经常会出现连接错误或某种排序错误(例如SQLException:关闭连接,NullPointerException:连接关闭或关闭UCP),导致垃圾收集问题(长期GC会填满并导致GC最终失败)无论我添加到JVM多少内存。)
我发现OracleDataSource可以很好地处理那些没有使用大量批处理的应用程序。例如,我使用的另一个应用程序是文件处理应用程序,但它一次只能在一个文件上运行。 OracleDataSource在这种情况下运行良好。它似乎也适用于Web应用程序。我们有一个网络应用程序,我们在9个月前安装了OracleDataSource,没有任何问题。
我确信有一些方法可以使OracleDataSource和OracleConnectionPoolDataSource一样工作,但这对我有用。