更改数据源连接URL运行时 [英] Changing datasource connection url runtime

查看:136
本文介绍了更改数据源连接URL运行时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



目前,连接池的属性是通过外部定义的属性加载的。

我正在研究一个使用spring + hibernate + mysql和c3p0进行连接池的项目。 src。 (例如:$ {db_uname})

当我们创建spring bean时,一切都很好。



我们连接的数据库可能因为某些原因无法访问,我们希望切换主机。



需要实现回调,它应该连接到新主机并重新初始化池



有关如何覆盖的任何指针现有的数据源/连接池将优雅地帮助。



这是我的spring配置文件的样子

 <?xml version =1.0encoding =UTF-8?> 
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexmlns :tx =http://www.springframework.org/schema/tx
xmlns:context =http://www.springframework.org/schema/context
xmlns:util = http://www.springframework.org/schema/util
xsi:schemaLocation =
http://www.springframework.org/schema/beans
http:// www。 springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/ spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd\">

<! - 组件扫描 - >
< import resource =component-scans-1.xml/>
< import resource =component-scans-2.xml/>


< util:properties id =serviceManagerProperties
location =classpath:servicemanagers.properties/>

<! - - 属性文件 - >
< context:property-placeholder location =classpath:database.config.properties,classpath:framework.properties/>

<! - context:annotation-config / - >
< tx:注解驱动的事务管理器=transactionManager/>

< bean id =dataSource
class =org.springframework.jdbc.datasource.DriverManagerDataSource>
< / bean>

< bean id =transactionManagerclass =org.springframework.orm.jpa.JpaTransactionManager>
< property name =entityManagerFactoryref =entityManagerFactory/>
< / bean>

< context:mbean-server id =mbeanServer/>
< context:mbean-export server =mbeanServerdefault-domain =a.b.c/>

< bean id =cacheManagerfactory-method =getInstance
class =net.sf.ehcache.CacheManager/>

< bean class =net.sf.ehcache.management.ManagementServiceinit-method =init>
< constructor-arg ref =cacheManager/>
< constructor-arg ref =mbeanServer/>
< constructor-arg value =false/>
< constructor-arg value =false/>
< constructor-arg value =false/>
< constructor-arg value =true/>
< / bean>

< bean id =entityManagerFactory
class =org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =jpaVendorAdapterref =jpaAdapter/>
< property name =persistenceXmlLocationvalue =classpath *:META-INF / framework-persistence.xml/>
< property name =persistenceUnitNamevalue =PU-NAME/>
< property name =jpaProperties>
<道具>
< prop key =hibernate.format_sql> true< / prop>
< prop key =hibernate.dialect> org.hibernate.dialect.MySQLDialect< / prop>
< prop key =hibernate.cache.use_query_cache> $ {hibernate.cache.use_query_cache}< / prop>
< prop key =hibernate.cache.use_second_level_cache> $ {hibernate.cache.use_second_level_cache}< / prop>
< prop key =hibernate.cache.region.factory_class>
org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
< / prop>

< prop key =hibernate.ejb.cfgfile> hibernate.cfg.xml< / prop>
< prop key =hibernate.generate_statistics> true< / prop>


<! - 连线设定 - >
< prop key =hibernate.connection.driver_class>
com.mysql.jdbc.Driver
< / prop>
< prop key =hibernate.connection.url>
jdbc:mysql:// $ {dbhost} / $ {dbschema}?zeroDateTimeBehavior = convertToNull& amp; useUnicode = true& amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp;
< prop key =hibernate.connection.username> $ {dbuser}< / prop>
< prop key =hibernate.connection.password> $ {dbpass}< / prop>

<! - CONNECTION POOLING - >
< prop key =hibernate.connection.provider_class>
org.hibernate.connection.C3P0ConnectionProvider
< / prop>
< prop key =hibernate.c3p0.maxPoolSize> $ {hibernate.c3p0.maxSize}< / prop>
< prop key =hibernate.c3p0.minPoolSize> $ {hibernate.c3p0.minSize}< / prop>
< prop key =hibernate.c3p0.acquireIncrement> $ {hibernate.c3p0.acquireIncrement}< / prop>
< prop key =hibernate.c3p0.idleConnectionTestPeriod> $ {hibernate.c3p0.idleTestPeriod}< / prop>
< prop key =hibernate.c3p0.maxStatements> $ {hibernate.c3p0.maxStatements}< / prop>
< prop key =hibernate.c3p0.timeout> $ {hibernate.c3p0.timeout}< / prop>

< /道具>
< / property>
< / bean>

< bean id =jpaAdapter
class =org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter/>



假设数据库模式是正确的,可以说我在事件中获取数据库凭证和主机信息,我需要'重新设置'连接池。 解决方案

 < beans:bean id =dataSource
class =org.springframework.aop.framework.ProxyFactoryBean>
< beans:property name =targetSourceref =swappableDataSource/>
< / beans:bean>

< beans:bean id =dummyDataSourceclass =com.mchange.v2.c3p0.ComboPooledDataSource
destroy-method =close/>

< beans:bean name =swappableDataSource
class =org.springframework.aop.target.HotSwappableTargetSource>
< beans:constructor-arg ref =dummyDataSource/>
< / beans:bean>

以及您的代码中的某些位置您可以执行此操作。

  @Autowired 
HotSwappableTargetSource swapable;

public void changeDatasource()抛出异常
{
swapable.swap(createNewSource();

}


ComboPooledDataSource createNewSource()抛出异常{
ComboPooledDataSource ds2 = new ComboPooledDataSource();
ds2.setJdbcUrl(url);
ds2.setDriverClass(driver);
ds2。 setUser(username);
ds2.setPassword(password);


return ds2;
}


I am working on a project which uses spring + hibernate + mysql and c3p0 for connection pooling.

Currently the properties for the connection pool are loaded via properties defined outside the src. (eg: ${db_uname})

Everything starts fine when we create the spring bean.

It might so happen that the database to which we have connected is inaccessible for some reason, and we would like to switch hosts.

Need to implement a call back, where it is supposed to connect to the new host and re-initialize the pool

Any pointers on how to override the existing data source / connection pool gracefully would be of great help.

Here is how my spring config file looks like

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<!-- Component scans -->
<import resource="component-scans-1.xml" />
<import resource="component-scans-2.xml" />


<util:properties id="serviceManagerProperties" 
    location="classpath:servicemanagers.properties" />

<!-- Properties file -->
<context:property-placeholder location="classpath:database.config.properties,classpath:framework.properties" />

<!-- context:annotation-config / -->
<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<context:mbean-server id="mbeanServer" />
<context:mbean-export server="mbeanServer" default-domain="a.b.c" />

<bean id="cacheManager" factory-method="getInstance"
    class="net.sf.ehcache.CacheManager" />

<bean class="net.sf.ehcache.management.ManagementService" init-method="init">
    <constructor-arg ref="cacheManager" />
    <constructor-arg ref="mbeanServer" />
    <constructor-arg value="false" />
    <constructor-arg value="false" />
    <constructor-arg value="false" />
    <constructor-arg value="true" />
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaAdapter" />
    <property name="persistenceXmlLocation" value="classpath*:META-INF/framework-persistence.xml" />
    <property name="persistenceUnitName" value="PU-NAME" />
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
            <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
            <prop key="hibernate.cache.region.factory_class">
                org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
            </prop>

            <prop key="hibernate.ejb.cfgfile">hibernate.cfg.xml</prop>
            <prop key="hibernate.generate_statistics">true</prop>


            <!-- CONNECTION SETTINGS -->
            <prop key="hibernate.connection.driver_class">
                com.mysql.jdbc.Driver
            </prop>
            <prop key="hibernate.connection.url">
                jdbc:mysql://${dbhost}/${dbschema}?zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;characterEncoding=UTF-8
            </prop>
            <prop key="hibernate.connection.username">${dbuser}</prop>
            <prop key="hibernate.connection.password">${dbpass}</prop>

            <!-- CONNECTION POOLING -->
            <prop key="hibernate.connection.provider_class">
                org.hibernate.connection.C3P0ConnectionProvider
            </prop>
            <prop key="hibernate.c3p0.maxPoolSize">${hibernate.c3p0.maxSize}</prop>
            <prop key="hibernate.c3p0.minPoolSize">${hibernate.c3p0.minSize}</prop>
            <prop key="hibernate.c3p0.acquireIncrement">${hibernate.c3p0.acquireIncrement}</prop>
            <prop key="hibernate.c3p0.idleConnectionTestPeriod">${hibernate.c3p0.idleTestPeriod}</prop>
            <prop key="hibernate.c3p0.maxStatements">${hibernate.c3p0.maxStatements}</prop>
            <prop key="hibernate.c3p0.timeout">${hibernate.c3p0.timeout}</prop>

        </props>
    </property>
</bean>

<bean id="jpaAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

Assuming the database schema is right, lets say i get the database credentials and the host information in the event, i need to 're-set' the connection pool.

解决方案

<beans:bean id="dataSource"
    class="org.springframework.aop.framework.ProxyFactoryBean">
    <beans:property name="targetSource" ref="swappableDataSource" />
</beans:bean>

<beans:bean id="dummyDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close" />

<beans:bean name="swappableDataSource"
    class="org.springframework.aop.target.HotSwappableTargetSource">
    <beans:constructor-arg ref="dummyDataSource" />
</beans:bean>

and some where in your code you can do this.

@Autowired
HotSwappableTargetSource swapable;

public void changeDatasource() throws Exception
{
            swapable.swap(createNewSource();

}


ComboPooledDataSource createNewSource() throws Exception {
    ComboPooledDataSource ds2 = new ComboPooledDataSource();
    ds2.setJdbcUrl(url);
    ds2.setDriverClass(driver);
    ds2.setUser(username);
    ds2.setPassword(password);


    return ds2;
}

这篇关于更改数据源连接URL运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆