一、采用读写分离技术的目标

随着网站的业务不断扩展,数据不断增加,用户越来越多,数据库的压力也就越来越大,采用传统的方式,比如:数据库或者SQL的优化基本已达不到要求,这个时候可以采用读写分离的策略来改变现状。采用读写分离技术能够有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库,从而保证系统的健壮性。

二、常用的两种方式

1、定义两个数据库链接,一个是masterDataSource,另个是slaveDataSource,更新数据时读取masterDataSource,查询是读取slaveDataSource。

2、动态数据源切换,在程序运行时,把数据源动态织如入程序中,从而选择主库还是从库。主要技术采用annotation,Spring AOP,反射,接下来详细介绍该种方法。

三、动态数据源切换实现读写分离

1,定义DataSource注解

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface DataSource {

String value();

}

2,继承抽象类AbstractRoutingDataSource来实现DynamicDataSource方法

public class DynamicDataSource extends AbstractRoutingDataSource{

public static final Logger logger = Logger.getLogger(DynamicDataSource.class.toString());

@Override

protected Object determineCurrentLookupKey() {

return DynamicDataSourceHolder.getDataSource();

}

}

3,定义DynamicDataSourceHolder方法

public class DynamicDataSourceHolder {

private static final ThreadLocal<String> holder = new ThreadLocal<String>();

public static void setDataSource(String name) {

holder.set(name);

}

public static String getDataSource() {

return holder.get();

}

}

4,定义DataSourceAspect类,在程序运行时动态切换数据源

public class DataSourceAspect {

public void before(JoinPoint point){

Object target = point.getTarget();

String method = point.getSignature().getName();

Class<?>[] classz = target.getClass().getInterfaces();

Class<?>[] parameterTypes = ((MethodSignature)point.getSignature()).getParameterTypes();

try{

Method m = classz[0].getMethod(method, parameterTypes);

if(m != null && m.isAnnotationPresent(DataSource.class)){

DataSource date = m.getAnnotation(DataSource.class);

DynamicDataSourceHolder.setDataSource(date.value());

}

else {

// 默认master

DynamicDataSourceHolder.setDataSource("master");

}

}catch(Exception e){

}

}

}

5,applicationContext-dataSource.xml配置

分别定义主从数据源后,再添加选择数据源的bean

<bean id="dataSource" class="****">

<property name="targetDataSources">

<map key-type="java.lang.String">

<entry key="master" value-ref="masterDataSource"/>

<entry key="slave" value-ref="slaveDataSource"/>

</map>

</property>

<property name="defaultTargetDataSource" ref="masterDataSource"/>

</bean>

增加aop配置

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>      <bean id="manyDataSourceAspect" class="****.DataSourceAspect" />

<aop:config>

<aop:aspect id="c" ref="manyDataSourceAspect">

<aop:before method="before" pointcut="execution(* *****.data.dao.*.*(..))"></aop:before>

</aop:aspect>

</aop:config>

6,DAO层定义方法的数据源

@DataSource(value="slave")

public ImUser findById(int id);

Spring aop读写分离的更多相关文章

  1. ssm maven spring AOP读写分离

    ssm maven spring AOP读写分离 总体流程 配置最开始写在pom.xml文件,解析到数据库配置文件,再解析到spring配置文件. 自定义注解DataSource:通过这个注解并且在s ...

  2. java 使用spring实现读写分离

    最近上线的项目中数据库数据已经临近饱和,最大的一张表数据已经接近3000W,百万数据的表也有几张,项目要求读数据(select)时间不能超过0.05秒,但实际情况已经不符合要求,explain建立索引 ...

  3. spring实现读写分离

    (转自:http://www.cnblogs.com/surge/p/3582248.html) 现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数 ...

  4. 使用Spring实现读写分离( MySQL实现主从复制)

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt403 1.  背景 我们一般应用对数据库而言都是"读多写少&quo ...

  5. Spring 数据库读写分离

    读写分离常见有俩种方式 1 第一种方式比较常用就是定义2个数据库连接,一个是Master,另一个是Slave.更新数据时我们取Master,查询数据时取Slave.太过简单不做介绍. 2 第二种方数据 ...

  6. Spring + Mybatis 读写分离

    项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 实现思路是: 第一步,实现动态切换数据源:配置两个DataSource,配置两个SqlSessionFactory指向两 ...

  7. 使用Spring实现读写分离( MySQL实现主从复制)(转)

    本文转自:http://blog.csdn.net/jack85986370/article/details/51559232 1.  背景 我们一般应用对数据库而言都是“读多写少”,也就说对数据库读 ...

  8. 002-使用Spring实现读写分离(MySQL实现主从复制)

    一. 背景 一般应用对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大主库,负责写入数据,我们称之为:写库:从库,负责读取数据,我们称之为:读库: 1. 读库和写库的数据一致:2. 写数 ...

  9. [转]Spring数据库读写分离

    数据库的读写分离简单的说是把对数据库的读和写操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力. 主(master)数据库提供写操作,从(slave)数据库提供读操作,其实在 ...

随机推荐

  1. SP34096 DIVCNTK - Counting Divisors (general)(Min_25筛)

    题面 洛谷 \(\sigma_0(i)\) 表示\(i\) 的约数个数 求\(S_k(n)=\sum_{i=1}^n\sigma_0(i^k)\mod 2^{64}\) 多测,\(T\le10^4,n ...

  2. linux进程池模型

    static int nchildren;static pid_t* pids;int main(int argc,char**argv){ int listenfd,i; socklen_t add ...

  3. CF912E Prime Gift 数学

    Opposite to Grisha's nice behavior, Oleg, though he has an entire year at his disposal, didn't manag ...

  4. zabbix发送邮件脚本

    #!/usr/bin/env python #-*- coding: UTF- -*- import os,sys reload(sys) sys.setdefaultencoding('utf8') ...

  5. 使用cookie实现自动登录

    一.从登录——>主页面,进行的过程是,输入 用户名和密码,以及验证码,点击“登录”跳转到Activity.jsp login1.action(跳转到登录页面) /** 跳转到login(有积分排 ...

  6. docker搭建数据库主从复制

    首先需要安装docker镜像: docker pull mysql:5.7 由于需要启动数据库才可以进入数据修改my.cnf文件,可以选择安装vi命令,也可以选择挂在 在此选择是挂载的方法进行安装: ...

  7. (转)TestNG框架提供两种传入参数的方法:

    1.从testng.xml传入参数. 如果参数是一些简单的值,可以直接在testng.xml中定义.这也是最常用的一种. 可以在测试用例中给参数一个默认值.这样,即使在xml文件中没有这个变量,你的测 ...

  8. svn 常用忽略

    *.o *.lo *.la *.al .libs *.so *.so.[-]* *.a *.pyc *.pyo __pycache__ *.rej *~ #*# .#* .*.swp .DS_Stor ...

  9. laravel 用户名登录

    laravel 用户名登录 默认登录设置为用户登录 laravel 5.3+ 修改文件(app\Http\Controllers\Auth\LoginController.php)增加 public ...

  10. 批处理中setlocal enabledelayedexpansion的含义

    setlocal enabledelayedexpansion       延迟变量全称"延迟环境变量扩展",要理解这个东西,我们还得先理解一下什么叫扩展!       CMD在解 ...