【问题标题】:Configure c3p0 in spring application context (intSQL and timezone)在 spring 应用程序上下文中配置 c3p0(intSQL 和时区)
【发布时间】:2023-04-03 22:14:01
【问题描述】:

如何在spring应用上下文中配置c3p0?

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

extensions 的 c3p0 文档说:

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

user extensions to configurations 的 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>

但是什么也没发生,它不会抛出错误,但不会像预期的那样运行。

【问题讨论】:

    标签: spring c3p0 spring-mybatis


    【解决方案1】:

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

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

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

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

    如果你想在获取连接时执行一些 SQL,你需要使用 ConnectionCustomizer 和你创建的 extensions 映射。 (你可以在他们的文档中看到它here

    例子:

    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>
    

    【讨论】:

    • 那太好了。非常感谢您的帮助。仅供参考,这里是包含类似功能的 InitSqlConnectionCustomizer 的 javadocs:github.com/swaldman/c3p0/blob/…
    【解决方案2】:

    编辑:不是一个好主意。最好遵循 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 2015-08-31
      • 1970-01-01
      • 2012-05-05
      相关资源
      最近更新 更多