4

我很确定其他人已经问过这个问题,但我仍然找不到满意的答案。所以,这是我的场景:我想使用 Oracle 的 JDBC 驱动程序隐式语句缓存(记录在这里:http ://docs.oracle.com/cd/B28359_01/java.111/b31224/stmtcach.htm#i1072607 )

我需要使用来自第 3 方 JDBC 池提供程序(更具体地说,是 Tomcat JDBC)的连接,但我别无选择。

问题是启用隐式缓存的方法是一个两步过程(根据文档):

1.

在连接上调用 setImplicitCachingEnabled(true) 或调用 OracleDataSource.getConnection 并将 ImplicitCachingEnabled 属性设置为 true。您通过调用 OracleDataSource.setImplicitCachingEnabled(true) 设置 ImplicitCachingEnabled

2.

除了调用这些方法之一,您还需要在物理连接上调用 OracleConnection.setStatementCacheSize。您提供的参数是缓存中的最大语句数。参数 0 指定不缓存。

我可以忍受 1 (不知何故,我可以将我的池配置OracleDataSource为用作主要连接工厂,并在其上设置OracleDataSource.setImplicitCachingEnabled(true))。但在第二步,我已经需要存在连接才能调用setStatementCacheSize.

我的问题是是否有可能在数据源级别指定默认值,statementCacheSize以便我可以从OracleDataSource已经启用隐式缓存的连接中获取。

PS:我在这里找到了一些相关的问题: Oracle jdbc driver:implicit statement cache or setPoolable(true)?

更新(可能的解决方案):

最终我这样做了:

  1. 使用 . 创建了本机连接池oracle.jdbc.pool.OracleDataSource
  2. 使用本机连接池创建了一个 tomcat JDBC 连接池org.apache.tomcat.jdbc.pool.DataSource(请参阅属性dataSource)。
  3. 通过 AOP 启用一个切入点,以便在执行 'execution(public java.sql.Connection oracle.jdbc.pool.OracleDataSource.getConnection())' 后我拾取对象并执行我想要的设置。

该解决方案效果很好;我只是不高兴我不得不写一些样板来做到这一点(我期待一个直截了当的属性)。

4

2 回答 2

6

白皮书Oracle JDBC 内存管理

11.2 驱动程序还添加了一个新属性来启用隐式语句缓存。

oracle.jdbc.implicitStatementCacheSize

该属性的值是一个整数字符串,例如“100”。它是语句缓存的初始大小。将该属性设置为正值会启用隐式语句缓存。默认值为“0”。该属性可以通过 -D 设置为系统属性,也可以通过 getConnection 设置为连接属性。

于 2016-05-06T08:50:50.330 回答
1

您只能通过OracleConnection.setStatementCacheSize方法更改语句缓存大小。

OracleConnection.setStatementCacheSize您可以创建一个JDBC 拦截器,而不是修改您的应用程序以在每个连接上调用。

@Override
public void reset(ConnectionPool pool, PooledConnection connection) {

    if (connection == null) {
        return;
    }

    Connection original = connection.getConnection();

    if (!(original instanceof OracleConnection)) {
        return;
    }

    try {
        if (!((OracleConnection) original).getImplicitCachingEnabled() && implicitCachingEnabled) {

            ((OracleConnection) original).setImplicitCachingEnabled(implicitCachingEnabled);

            log.info("Activated statement cache");

            ((OracleConnection) original).setStatementCacheSize(statementCacheSize);

            log.info("Statement cache size set to " + statementCacheSize);
        }
    } catch (SQLException e) {
        log.error(e.getMessage(), e);
    }
}
于 2013-04-09T17:53:28.440 回答