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

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. MySQL导入SQL语句报错 : MySQL server has gone away (已解决)

    MySQL server has gone away 解决的方法其实很简单,我相信也有很多人遇到了这个问题.比如DZ论坛,安装好服务器,但是清空缓存等操作数据库的动作,运行时间稍长就会出现 MySQL ...

  2. 基于dsp_builder的算法在FPGA上的实现(转自https://www.cnblogs.com/sunev/archive/2012/11/17/2774836.html)

    一.摘要 结合dsp_builder.matlab.modelsim和quartus ii等软件完成算法的FPGA实现. 二.实验平台 硬件平台:DIY_DE2 软件平台:quartus ii9.0 ...

  3. 六.使用python操作mysql数据库

    数据库的安装和连接 pymysql的安装              pip install PyMySQL python连接数据库 import pymysql db = pymysql.connec ...

  4. JDK、JRE、JVM之间的关系

       JDK.JRE.JVM之间的关系 1.JDK下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads ...

  5. 背水一战 Windows 10 (69) - 控件(控件基类): UIElement - Manipulate 手势处理, 路由事件的注册, 路由事件的冒泡, 命中测试的可见性

    [源码下载] 背水一战 Windows 10 (69) - 控件(控件基类): UIElement - Manipulate 手势处理, 路由事件的注册, 路由事件的冒泡, 命中测试的可见性 作者:w ...

  6. 利用PHP扩展Taint找出网站的潜在安全漏洞实践

    一.背景 笔者从接触计算机后就对网络安全一直比较感兴趣,在做PHP开发后对web安全一直比较关注,2016时无意中发现Taint这个扩展,体验之后发现确实好用:不过当时在查询相关资料时候发现关注此扩展 ...

  7. js中的类

    概述 经典的老书害人啊,全是讨论怎么解决javascript里面用函数形式定义类的坑.结果es2015直接用class关键字解决了所有问题.虽然class关键字没有什么新东西,只是js现有继承结构的语 ...

  8. 学习Python语言 基础语法:变量的基本使用

    Python变量 程序是用来处理数据的,变量就是用来保存数据的,通过给数据定义一个名称来保证方便记忆和识别.使用这个数据.变量可以保存所有类型的数据. Python变量的定义 在Python中,变量的 ...

  9. Linux - 基础命令汇总

    珠玉在前,不再赘言. 60个命令 对Linux新手非常有用的20个命令 对中级Linux用户非常有用的20个命令 对Linux专家非常有用的20个命令 一些技巧 最实用的 Linux 命令行使用技巧 ...

  10. 课程四(Convolutional Neural Networks),第三 周(Object detection) —— 0.Learning Goals

    Learning Goals: Understand the challenges of Object Localization, Object Detection and Landmark Find ...