Spring configures multiple data sources and enables dynamic switching

Source: Internet
Author: User
Tags throwable

1. Configure two different data sources, as follows

<!--data Source configuration 1--
<bean id= "TestDataSource1" class= "Com.alibaba.druid.pool.DruidDataSource" init-method= "Init" destroy-method= " Close ">
<property name= "Driverclassname" value= "${db.driver}"/>
<property name= "url" value= "${unity.db.jdbc.url}"/>
<property name= "username" value= "${db.login.name}" ></property>
<property name= "Password" value= "${db.login.password}"/>
<property name= "Filters" value= "${db.filters}" ></property>
<property name= "maxactive" value= "${db.pool.maxactive}" ></property>
<property name= "InitialSize" value= "${db.pool.initialsize}" ></property>
<property name= "Minidle" value= "${db.pool.minidle}" ></property>
<property name= "maxwait" value= "${db.maxwait}" ></property>
<property name= "Timebetweenevictionrunsmillis" value= "${db.timebetweenevictionrunsmillis}" ></property >
<property name= "Minevictableidletimemillis" value= "${db.minevictableidletimemillis}" ></property>
<property name= "Validationquery" value= "${db.validationquery}" ></property>
<property name= "Testwhileidle" value= "${db.testwhileidle}" ></property>
<property name= "Testonborrow" value= "${db.testonborrow}" ></property>
<property name= "Testonreturn" value= "${db.testonreturn}" ></property>
<property name= "poolpreparedstatements" value= "${db.poolpreparedstatements}" ></property>
<property name= "maxopenpreparedstatements" value= "${db.maxopenpreparedstatements}" ></property>
<!--monitoring database--
<property name= "Proxyfilters" >
<list>
<ref bean= "Log-filter"/>
</list>
</property>

</bean>

<!--data Source Configuration 2--
<bean id= "TestDataSource2" class= "Com.alibaba.druid.pool.DruidDataSource" init-method= "Init" destroy-method= " Close ">
<property name= "Driverclassname" value= "${db.driver}"/>
<property name= "url" value= "${pub.db.jdbc.url}"/>
<property name= "username" value= "${db.login.name}" ></property>
<property name= "Password" value= "${db.login.password}"/>
<property name= "Filters" value= "${db.filters}" ></property>
<property name= "maxactive" value= "${db.pool.maxactive}" ></property>
<property name= "InitialSize" value= "${db.pool.initialsize}" ></property>
<property name= "Minidle" value= "${db.pool.minidle}" ></property>
<property name= "maxwait" value= "${db.maxwait}" ></property>
<property name= "Timebetweenevictionrunsmillis" value= "${db.timebetweenevictionrunsmillis}" ></property >
<property name= "Minevictableidletimemillis" value= "${db.minevictableidletimemillis}" ></property>
<property name= "Validationquery" value= "${db.validationquery}" ></property>
<property name= "Testwhileidle" value= "${db.testwhileidle}" ></property>
<property name= "Testonborrow" value= "${db.testonborrow}" ></property>
<property name= "Testonreturn" value= "${db.testonreturn}" ></property>
<property name= "poolpreparedstatements" value= "${db.poolpreparedstatements}" ></property>
<property name= "maxopenpreparedstatements" value= "${db.maxopenpreparedstatements}" ></property>
<!--monitoring database--
<property name= "Proxyfilters" >
<list>
<ref bean= "Log-filter"/>
</list>
</property>

</bean>

2. Define a class inheritance Abstractroutingdatasource implementation Determinecurrentlookupkey method, this method can realize the dynamic switch of the database, as follows:

public class Dynamicdatasource extends Abstractroutingdatasource {
@Override
Protected Object Determinecurrentlookupkey () {
return Datasourcecontextholder.getdatasourcetype ();
}
}

3. Define a tool class that can set variables for the current thread to set the corresponding data source name:

public class Datasourcecontextholder {
private static final threadlocal<string> Contextholder = new threadlocal<string> ();
/**
* @Description: Set the data source type
* @param datasourcetype Database type
* @return void
* @throws
*/
public static void Setdatasourcetype (String datasourcetype) {
Contextholder.set (DatasourceType);
}

/**
* @Description: Get data Source Type
* @param
* @return String
* @throws
*/
public static String Getdatasourcetype () {
return Contextholder.get ();
}

/**
* @Description: Clear Data Source Type
* @param
* @return void
* @throws
*/
public static void Cleardatasourcetype () {
Contextholder.remove ();
}
}

It is then configured in spring as follows:

<!--to write a spring configuration file configuration Most source mapping relationships-
<bean class= "Com.sino.access.database.DynamicDataSource" id= "DataSource" >
<property name= "Targetdatasources" >
<map key-type= "Java.lang.String" >
<entry value-ref= "TestDataSource1" key= "<span style=" font-family:arial, Helvetica, Sans-serif; " >testdatasource1</span><span style= "font-family:arial, Helvetica, Sans-serif;" > "></entry></span>
<entry value-ref= "TestDataSource2" key= "TestDataSource2" ></entry>
</map>
</property>
<property name= "Defaulttargetdatasource" ref= "TestDataSource1" >
</property>
</bean>

This configures two data sources corresponding to the key TestDataSource1 and TestDataSource2 respectively, the default database is Testdatasource.
4. After completing the above steps, if there is no transaction management of the database, the dynamic switch of the database can be realized . However, if the transaction management of the database is involved, the database transaction must be switched on .

Otherwise, the database switchover will only take effect the next time the database operation occurs. You can define an AOP processing class to switch databases before the database transaction is opened, as follows:

public class Datasourceaspect implements Methodbeforeadvice,afterreturningadvice
{

@Override
public void afterreturning (Object returnvalue, method,
Object[] args, Object target) throws Throwable {
TODO auto-generated Method Stub
Datasourcecontextholder.cleardatasourcetype ();
}

@Override
public void before (method, object[] args, Object target)
Throws Throwable {

if (Method.isannotationpresent (Datasource.class))
{
DataSource DataSource = method.getannotation (Datasource.class);
Datasourcecontextholder.setdatasourcetype (Datasource.name ());
}
Else
{
Datasourcecontextholder.setdatasourcetype (SinoConstant.DataSourceType.unityDataSource.toString ());
}

}
}

5. Set the database transaction facets and the order in which the database slices are executed, as follows:

<aop:config>
<aop:pointcut id= "transactionpointcut" expression= "Execution (* com.test.service.*.* (..))"/>
<aop:advisor pointcut-ref= "Transactionpointcut"
advice-ref= "Txadvice" order= "2"/>
<aop:advisor advice-ref= "Datasourceexchange" pointcut-ref= "Transactionpointcut" order= "1"/>
</aop:config>

Use the Order property of AOP to set the sequence of execution so that the spring database dynamic switchover with transaction management is implemented.

Spring configures multiple data sources and enables dynamic switching

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.