2

如何在 Spring 应用程序上下文中配置 c3p0?

我正在运行 mybatis + spring + c3p0 + Oracle 11g。

用于扩展的 c3p0 文档说:

extensions 默认值:空的 java.util.Map 一个 java.util.Map(原始类型),包含为此 DataSource 定义的任何用户定义的配置扩展的值。

用户扩展配置的 c3p0 文档说:

<extensions>
  <property name="initSql">SET SCHEMA 'foo'</property>
  <property name="timezone">PDT</property>
</extensions>

因此,我将我的 spring 应用程序上下文配置为:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
    <property name="jdbcUrl" value="jdbc:oracle:thin:@//databasehost:1527/servicename" />
    <property name="user" ref="database.user" />
    <property name="password" ref="database.password" />
    <property name="extensions">
        <map>
            <entry key="initSql" value="ALTER SESSION SET CURRENT_SCHEMA = MY_SCHEMA" />
            <entry key="timezone" value="UTC" />
        </map>
    </property>
</bean>

但是没有任何反应,它不会引发错误,但不会按预期运行。

4

2 回答 2

2

您在回答中所做的不足以使其发挥作用。

如果你调查你的 mysql 日志,你会看到timezone设置永远不会生效(例如,不会有“set time_zone ...”语句执行)。

唯一在您的答案中生效的是:preferredTestQuery您已设置为alter session set current_schema=MY_SCHEMA.

这意味着每个Checkin (发生在您执行的几乎每个查询之前 - 即 TOO MUCH )也会调用alter session set current_schema=MY_SCHEMA这是一个非常糟糕的性能实践......

如果你想在获取连接时执行一些 SQL,你需要ConnectionCustomizer结合extensions你创建的 Map 使用。(您可以在此处的文档中看到它)

例子:

public class ExampleConnectionCustomizer extends AbstractConnectionCustomizer {
    public ExampleConnectionCustomizer () {
    }

    private String getInitSql(String parentDataSourceIdentityToken) {
        return (String)this.extensionsForToken(parentDataSourceIdentityToken).get("initSql");
    }

    public void onAcquire(Connection c, String pdsIdt) {
        String initSql = this.getInitSql(parentDataSourceIdentityToken);
        if(initSql != null) {
            Statement stmt = null;
            try {
                stmt = c.createStatement();
                stmt.executeUpdate(initSql);
            } finally {
                if(stmt != null) {
                    stmt.close();
                }
            }
        }
    }

}  


<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    ....The rest of your properties...
    <property name="preferredTestQuery" value="SELECT 1" /> <!--Much more efficient-->
    <property name="connectionCustomizerClassName" value="yourpackage.ExampleConnectionCustomizer" />
    <!-- extensions -->         
    <property name="extensions">
        <map>
            <entry key="initSql" value="alter session set current_schema=MY_SCHEMA" />
        </map>
    </property>
</bean>
于 2015-12-17T10:14:08.417 回答
-1

编辑:不是一个好主意。最好遵循 Shay Elkayam 的方法


经过大量挖掘后,我想出了这个完全可用的配置:

<!--
    DataSource with connection polling
    For more details, see: http://www.mchange.com/projects/c3p0/
 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
    <property name="jdbcUrl" value="jdbc:oracle:thin:@//hostaname:1527/servicename" />
    <property name="user" value="user" />
    <property name="password" value="password" />
    <!-- Other DataSource Configuration -->
    <property name="numHelperThreads" value="10" />
    <property name="maxAdministrativeTaskTime" value="10000" />
    <!-- pool sizing -->
    <property name="initialPoolSize" value="3" />
    <property name="minPoolSize" value="10" />
    <property name="maxPoolSize" value="35" />
    <property name="acquireIncrement" value="3" />
    <property name="maxStatements" value="0" />
    <!-- retries -->
    <property name="acquireRetryAttempts" value="30" />
    <property name="acquireRetryDelay" value="1000" /> <!-- 1s -->
    <property name="breakAfterAcquireFailure" value="false" />
    <!-- refreshing connections -->
    <property name="maxIdleTime" value="180" /> <!-- 3min -->
    <property name="maxConnectionAge" value="300" />
    <!-- timeouts and testing -->
    <property name="checkoutTimeout" value="5000" /> <!-- 5s -->
    <property name="idleConnectionTestPeriod" value="60" /> <!-- 60s -->
    <property name="testConnectionOnCheckout" value="true" />
    <property name="testConnectionOnCheckin" value="true" />
    <property name="preferredTestQuery" value="alter session set current_schema=MY_SCHEMA" />
    <!-- extensions -->         
    <property name="extensions">
        <map>
            <entry key="timezone" value="UTC" />
        </map>
    </property>
</bean>
于 2015-11-10T17:04:06.083 回答