Spring Dynamic switch Database support transactions

Source: Internet
Author: User
Tags connection pooling mysql in
There are multiple libraries for MySQL in the project, and the same method may manipulate different tables in the code. Learn a variety of ways on the Internet. Probably summed up a bit. 1.mycat, Cobar and other distributed database middleware. Can be very good support, but too heavy, for our project a bit overqualified. The 2.spring Abstractroutingdatasource enables database connection switching. The data source can be dynamically switched, but it has an impact on transactions and can be transactionally consistent with JTA, but less efficient. And our project transactions can meet the requirements in a single-library consistency. So that's the way it's used. The following is a concrete implementation process: 1) Configure multiple data sources in the spring configuration file.
<bean id= "DataSource" class= "Org.apache.commons.dbcp.BasicDataSource" destroy-method= "Close" > <property Name= "Driverclassname" value= "Com.mysql.jdbc.Driver"/> <property name= "url" value= "${mysql.url}"/> <
Property name= "username" value= "${mysql.username}"/> <property name= "password" value= "${mysql.password}"/> <!--initial value when connection pooling starts--<property name= "InitialSize" value= "1"/> <!-- The maximum idle value. After a peak time, the connection pool can slowly release a portion of the connection that has not been used, until it has been reduced to maxidle and <property name= "Maxidle" value= "2"/> <!--

Minimum idle value. When the number of idle connections is less than the threshold, the connection pool will pre-request some connections to avoid the performance overhead of applying the flood peak time--<property name= "Minidle" value= "1"/> </bean> <bean id= "Xiaomi" class= "Org.apache.commons.dbcp.BasicDataSource" destroy-method= "Close" > <property name= " Driverclassname "value=" Com.mysql.jdbc.Driver "/> <property name=" url "value=" ${mysql.url.xiaomi} "/> < Property name= "username" value= "${mysql.username}"/> <property name= "password" value= "${mysql.password}" /> <!--initial value when connection pooling starts--<property name= "InitialSize" value= "1"/> <!-- The maximum idle value. After a peak time, the connection pool can slowly release a portion of the connection that has not been used, until it has been reduced to maxidle and <property name= "Maxidle" value= "2"/> <!-- Minimum idle value. When the number of idle connections is less than the threshold, the connection pool will pre-request some connections to avoid the performance overhead of applying the flood peak time--<property name= "Minidle" value= "1"/> </bean>


2) define a Dynamic Data source
<bean class= "Com.futuren.wzk.common.datasource.DynamicDataSource"
id= "Dynamicdatasource" >
< Property name= "Targetdatasources" >
<map key-type= "java.lang.String" >
<entry value-ref= " DataSource "key=" Wzk "></entry>
<entry value-ref=" Xiaomi "key=" Xiaomi "></entry>
</ map>
</property>
<property name= "Defaulttargetdatasource" ref= "DataSource"/>
</ Bean>


3) Defining Dynamic Data sources and auxiliary classes
public class Dynamicdatasource extends Abstractroutingdatasource {
@Override
protected Object Determinecurrentlookupkey () {
String type = Datasourcecontextholder.getdatasourcetype ();
return type;
}
}

public class Datasourcecontextholder {
private static final threadlocal<string> Contextholder = new Threadlocal<string> ();

/**
* @Description: Set data Source Type
* @param datasourcetype
* Database type
* @return void
* @throws
*/< C15/>public static void Setdatasourcetype (String datasourcetype) {
contextholder.set (datasourcetype);
}

/**
* @Description: Gets the 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 ();
}
}


4) Modify the transaction manager's data source to be a dynamic data source, specifying that the transaction annotations are sorted to 2, we will specify that the toggle data source annotation is 1, so that before the transaction switch the data source, otherwise after the transaction after the switch, invalid.
<!--annotation transaction--
<bean id= "TransactionManager"
class= " Org.springframework.jdbc.datasource.DataSourceTransactionManager ">
<property name=" DataSource "ref=" Dynamicdatasource "/>
<!--enable Annotations--
<tx:annotation-driven transaction-manager=" TransactionManager "order=" 2 "/>


5) define the switch database annotations and AOP facets, specify a sort of 1, here is a question, through the pointcut to get the annotation data of the proxy method, I use the reflection, but the internet has said can be directly as a parameter passed, I have not tried to succeed, do not know where the wrong, follow the guidance of the great God, you can share.
@Target ({elementtype.method, elementtype.type})
@Retention (retentionpolicy.runtime)
@Inherited
@ Documented public
@interface DataSource {
String name ();

}

@Component
@Aspect
@Order (1) Public
class Datasourceproxy {

@Before (value= "@annotation ( Com.futuren.wzk.common.datasource.DataSource) public
Void before (Joinpoint JP) {
String methodName = Jp.getsignature (). GetName ();
Method[] methods = Jp.gettarget (). GetClass (). GetMethods ();
for (Method method:methods) {
if (Method.getname (). Equals (MethodName)) {
DataSource ds = Method.getannotation (datasource.class);
Datasourcecontextholder.setdatasourcetype (Ds.name ());}}}


6) use in the project
@Override
@Transactional
@DataSource (name= "Ucenter") public
int addUser (user user) {
Usermapper.insert (user);
return User.getuid ();
}


This approach, which only supports library transactions, may introduce JTA, or other custom implementations, if you want to multi-library transactions. or any other technology I don't know about. Welcome to the discussion.

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.