在 spring 应用程序上下文中配置 c3p0(intSQL 和时区)
Configure c3p0 in spring application context (intSQL and timezone)
如何在 spring 应用上下文中配置 c3p0?
我是运行mybatis+spring+c3p0+Oracle 11g
extensions 的 c3p0 文档说:
extensions Default: an empty java.util.Map A java.util.Map (raw type)
containing the values of any user-defined configuration extensions
defined for this DataSource.
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>
但是没有任何反应,它不会抛出错误,但不会按预期运行。
编辑:这不是个好主意。最好遵循 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>
您在回答中所做的不足以使其发挥作用。
例如,如果您调查 mysql 日志,您会发现 timezone
设置永远不会生效(永远不会执行任何 "set time_zone..." 语句)。
唯一在您的答案中生效的是:preferredTestQuery
,您已将其设置为 alter session set current_schema=MY_SCHEMA
。
这意味着每个 Checkin(几乎在您执行的每个查询之前发生 - 即太多) 也会调用 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>
如何在 spring 应用上下文中配置 c3p0?
我是运行mybatis+spring+c3p0+Oracle 11g
extensions 的 c3p0 文档说:
extensions Default: an empty java.util.Map A java.util.Map (raw type) containing the values of any user-defined configuration extensions defined for this DataSource.
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>
但是没有任何反应,它不会抛出错误,但不会按预期运行。
编辑:这不是个好主意。最好遵循 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>
您在回答中所做的不足以使其发挥作用。
例如,如果您调查 mysql 日志,您会发现 timezone
设置永远不会生效(永远不会执行任何 "set time_zone..." 语句)。
唯一在您的答案中生效的是:preferredTestQuery
,您已将其设置为 alter session set current_schema=MY_SCHEMA
。
这意味着每个 Checkin(几乎在您执行的每个查询之前发生 - 即太多) 也会调用 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>