1

我一直在尝试将我的 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 根据从文件传递的数据创建费用请求。一个文件可以有数十万个费用请求。我的问题是堆中的长期内存正在填满并且没有释放对象。在我设置的性能测试中,垃圾收集中的长期内存在大约 20-25 分钟内被填满,并且永远不会释放。应用程序最终遇到 GC 限制超出异常并停止运行。

当我使用旧的 OracleConnectionCacheImpl 类运行相同的测试时,它运行起来没有问题。假设线程池和所有附带的代码都是使用旧版本的 Spring (1.2.6) 和旧的 ojdbc 驱动程序编写的,但是 OracleConnectionCacheImpl 的工作方式与通用连接池的工作方式真的有那么大的区别吗?如果我想适应 Oracle 的 JDBC 驱动程序代码的最新版本,我是否正在考虑重写我的域模型。我已经尝试过 OracleDataSource 连接,但在同时处理多个文件后,它因 NullPointerExceptions 而失败。然后我去了UCP(根据本论坛另一篇帖子的建议),它在除一个应用程序之外的所有应用程序中都可以正常工作。此时我' 我试图弄清楚我是否可以为我的数据源进一步优化 Spring 配置 bean,或者我是否需要开始考虑升级代码库。如前所述,这段代码在旧的 ojdbc 类上运行得非常好,但我在尝试实现 UCP 的每一步都遇到了问题。我开始怀疑它是否值得升级。

4

1 回答 1

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 应用程序。我们有一个 Web 应用程序,我们在 9 个月前安装了 OracleDataSource,并且没有出现任何问题。

我确信有办法让 OracleDataSource 和 OracleConnectionPoolDataSource 一样工作,但这对我有用。

于 2011-10-27T20:08:21.143 回答