多数据源问题很常见,例如读写分离数据库配置。

1、首先配置多个datasource

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver">
</property>
<property name="url" value="jdbc:jtds:sqlserver://xxx:1433;databaseName=XXX">
</property>
<property name="username" value="XXX"></property>
<property name="password" value="XXX"></property>
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver">
</property>
<property name="url" value="jdbc:jtds:sqlserver://XXX:1433;databaseName=XXX">
</property>
<property name="username" value="XXX"></property>
<property name="password" value="XXX"></property>
</bean>

2、写一个DynamicDataSource类继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法

package com.standard.core.util;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}

3、利用ThreadLocal解决线程安全问题

package com.standard.core.util;
public class CustomerContextHolder {
public static final String DATA_SOURCE_A = "dataSource";
public static final String DATA_SOURCE_B = "dataSource2";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}

4、数据源配置

<bean id="dynamicDataSource" class="com.standard.core.util.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource" key="dataSource"></entry>
<entry value-ref="dataSource2" key="dataSource2"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource" >
</property>
</bean>

5、利用拦截器,设置每个请求线程的CustomerContextHolder

public class DatabaseInterceptor implements Interceptor {

    private static final Logger DB_INC_LOG = LoggerFactory.getLogger(DatabaseInterceptor.class);

    @Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
try {
Method method = methodInvocation.getMethod();
if (method != null && method.getAnnotation(ReadOnlyDataSource.class) != null) {
DataSourceProvider.setDataSource(AvailableDataSources.READ);
}
return methodInvocation.proceed();
} finally {
DataSourceProvider.clearDataSource();
}

6、重写AbstractRoutingDataSource的方法determineCurrentLookupKey(),切换数据源,切换读写

@Override
protected Object determineCurrentLookupKey() {
if (System.currentTimeMillis() - RWSplittingClosed_cache_time <= RW_SPLITTING_CLOSED_TIMEOUT) {
if (RWSplittingClosed_cache) {
return AvailableDataSources.WRITE;
}
return DataSourceProvider.getDataSource();
}
Jedis jedis = null;
try {
jedis = pingJedis();
if (jedis == null) {
return AvailableDataSources.WRITE;
}
Boolean masterForced = Boolean.valueOf(jedis.get(Constants.RW_SPLITTING_CLOSED));
RWSplittingClosed_cache = masterForced;
RWSplittingClosed_cache_time = System.currentTimeMillis();
if (masterForced) {
return AvailableDataSources.WRITE;
}
return DataSourceProvider.getDataSource();
} catch (Exception e) {
log.error(e.getMessage());
return AvailableDataSources.WRITE;
} finally {
if (jedis != null) {
pool.returnResource(jedis);
}
}
}
 

【Spring】26、利用Spring的AbstractRoutingDataSource解决多数据源,读写分离问题的更多相关文章

  1. 利用Spring的AbstractRoutingDataSource解决多数据源的问题【代码手动切换,非AOP】

    转: 利用Spring的AbstractRoutingDataSource解决多数据源的问题 多数据源问题很常见,例如读写分离数据库配置. 原来的项目出现了新需求,局方要求新增某服务器用以提供某代码, ...

  2. 利用Spring的AbstractRoutingDataSource解决多数据源的问题

    多数据源问题很常见,例如读写分离数据库配置. 原来的项目出现了新需求,局方要求新增某服务器用以提供某代码,涉及到多数据源的问题. 解决方法如下: 1.首先配置多个datasource <bean ...

  3. Spring配置动态数据源-读写分离和多数据源

    在现在互联网系统中,随着用户量的增长,单数据源通常无法满足系统的负载要求.因此为了解决用户量增长带来的压力,在数据库层面会采用读写分离技术和数据库拆分等技术.读写分离就是就是一个Master数据库,多 ...

  4. 【Spring】Spring如何实现多数据源读写分离?这是我看过最详细的一篇!!

    写在前面 很多小伙伴私聊我说:最近他们公司的业务涉及到多个数据源的问题,问我Spring如何实现多数据源的问题.回答这个问题之前,首先需要弄懂什么是多数据源:多数据源就是在同一个项目中,会连接两个甚至 ...

  5. 【Spring】利用Spring最简单地使用异步方法

    有时候我们想异步地调用某个方法. 比如这个场景:在业务处理完毕后,需给用户发送通知邮件.由于邮件发送需调用邮箱服务商,有可能发生阻塞,我们就可以异步调用.当然有个前提,即如果邮件发送失败,不需要提示用 ...

  6. 【Spring】利用spring的JdbcTemplate查询返回结果映射到自定义类型

    // org.springframework.jdbc.core.JdbcTemplate 中的查询方法基本都有支持参数RowMapper<T> rowMapper的重载方法.下面只是随便 ...

  7. spring项目配置双数据源读写分离

    我们最早做新项目的时候一直想做数据库的读写分离与主从同步,由于一些原因一直没有去做这个事情,这次我们需要配置双数据源的起因是因为我们做了一个新项目用了另一个数据库,需要把这个数据库的数据显示到原来的后 ...

  8. 在应用层通过spring特性解决数据库读写分离

    如何配置mysql数据库的主从? 单机配置mysql主从:http://my.oschina.net/god/blog/496 常见的解决数据库读写分离有两种方案 1.应用层 http://neore ...

  9. 使用Spring AOP实现读写分离(MySql实现主从复制)

    1.  背景 我们一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,有一个思路就是说采用数据库集群的方案,其中一个是主库,负责写入数据,我们称之为:写库: 其它都是从库,负责读 ...

随机推荐

  1. [solution] JZOJ-5795 词典

    [solution]JZOJ-5795 词典 题面 Description 小C有$n$个字符串$T_1 T_n$,给出$m$个询问 第$i$个询问给出一个字符串$S_i$,对于每个询问,我们可以得到 ...

  2. Http协议和Tomcat服务器

    Http协议和Tomcat服务器 什么是Http协议 HTTP,超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议. Http协议的组成 Ht ...

  3. ZZ:git只clone仓库中指定子目录和指定文件的实现

    原文链接: http://blog.csdn.net/xuyaqun/article/details/49275477 git目前唯一不能实现的是:不能像svn那样,针对子目录设置权限,这与git分布 ...

  4. javascript知识整理之this

    js中的this是一个头疼的问题,尤其对于笔者这种初级的菜鸟来讲,下面梳理下this的知识,可以当做是初级进阶也好入门也罢,总归输出的才是自己掌握的: Js中this不是由词法作用域决定的 而是调用时 ...

  5. 前端学习之路-CSS介绍,Html介绍,JavaScript介绍

    CSS介绍 学前端必备掌握CSS样式,css为层叠样式表,用来定义页面的显示效果,加强用户的体验乐趣,那么如何用css到html中呢? style属性方式 利用标签中的style属性来改变显示样式 & ...

  6. Shell-18--正则表达式

    a*  a出现0或任意次,没有意义,会全输出

  7. PHP错误处理函数register_shutdown_function

    当程序在线上运行时,如果遇到BUG,想不在前端输出错误信息,同时能及时邮件通知开发者,register_shutdown_function函数就可以派上用场了. 注册一个会在脚本执行完成或者 exit ...

  8. 纯css实现不同方向的三角形

    .triangle { position: relative; &:after { position: absolute; top: 50%; transform: translate(0,- ...

  9. java-null简介

    对于每一个Java程序员来说,null肯定是一个让人头痛的东西,连Java的发明者都承认这是一项巨大的设计失误,今天就来总结一下Java中关于null的知识. 1.null不属于任何类型,可以被转换成 ...

  10. [EXP]K8 jboss invoke deploy getshell exploit

    MSF jboss invoke deploy EXPLOIT moudle Date:2013.11.28 Author:K8gege 改这个EXP中 过程有点不进人意 没能在一个payload里直 ...