摘要 关注公众号回复关键字【 基于Spring的数据库读写分离 】获取完整实现代码。...数据库读写分离 MySQL主从数据库搭建 基于AbstractRoutingDataSource实现多数据源切换 @Transactional 测试 1.数据库读写分离 数据库读写分离的实现主要有两种方式...本文的实现我们基于Spring的AbstractRoutingDataSource来实现。 2....主从数据库搭建 # 假设你现在已经在dbrouter模块(目录)下 cd master-slave-db ./start.sh 使用start.sh可以一键搭建MySQL主从数据库。...@Transactional 通过@Transactional开启事务以后,在获取到数据源建立连接后,后面不会再对数据源进行切完,直至整个事务完成。
1.2 读写分离 一些规模较小的公司,没有使用数据库访问层中间件。使用多数据源来实现简单的读写分离功能。 ? 这里的架构与上图类似。...不同的是,在读写分离中,主库和从库的数据库是一致的(不考虑主从延迟)。数据更新操作(insert、update、delete)都是在主库上进行,主库将数据变更信息同步给从库。...如果使用了数据库访问层中间件,通常会有中间件来实现读写分离的逻辑,对业务更加透明。...另外,一点需要注意的是,在事务中无法切换数据源。spring的@Transactional注解,无非一个切入点,spring会对添加了@Transactional注解方法的类进行代理。...2、@Routing注解和spring提供的@Transactional注解,都需要对类进行代理,且前者需要在后者之前发挥作用。是使用二次代理?还是其他更优雅的方式
引言 读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做。因此,一般来讲,读写分离有两种实现方式。...然而,应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点,因为数据源配置都是写在配置中的,新增数据库意味着新加一个数据源,必然改配置,并重启应用。当然,好处就是相对简单。 ?...AbstractRoutingDataSource 基于特定的查找key路由到特定的数据源。它内部维护了一组目标数据源,并且做了路由key与目标数据源之间的映射,提供基于key查找数据源的方法。 ?...容器中现在有4个数据源,所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。...设置路由key / 查找数据源 目标数据源就是那前3个这个我们是知道的,但是使用的时候是如果查找数据源的呢?
引言 读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做。因此,一般来讲,读写分离有两种实现方式。...这里我们选择程序自己来做,主要是利用Spring提供的路由数据源,以及AOP 然而,应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点,因为数据源配置都是写在配置中的,新增数据库意味着新加一个数据源...AbstractRoutingDataSource 基于特定的查找key路由到特定的数据源。它内部维护了一组目标数据源,并且做了路由key与目标数据源之间的映射,提供基于key查找数据源的方法。...容器中现在有4个数据源,所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。...设置路由key / 查找数据源 目标数据源就是那前3个这个我们是知道的,但是使用的时候是如果查找数据源的呢?
在大型应用程序中,配置主从数据库并使用读写分离是常见的设计模式。在Spring应用程序中,要实现读写分离,最好不要对现有代码进行改动,而是在底层透明地支持。...在开发环境下,没有必要配置主从数据库。只需要给数据库设置两个用户,一个rw具有读写权限,一个ro只有SELECT权限,这样就模拟了生产环境下对主从数据库的读写分离。...我们仔细想想,Spring提供的声明式事务管理,就只需要一个@Transactional()注解,放在某个Java方法上,这个方法就自动具有了事务。...想要在应用程序中少写代码,我们就得多做一点底层工作:必须使用类似Spring实现声明式事务的机制,即用AOP实现动态数据源切换。...此外,@RoutingWith和@Transactional混用时,要设定AOP的优先级。 本文代码需要SpringBoot支持,JDK 1.8编译并打开-parameters编译参数。
: master: 使用了多数据源的 RESTful API 接口,使用 Druid 实现了 DAO 层数据源动态切换和只读数据源负载均衡 dev: 最简单的切面和注解方式实现的动态数据源切换...druid: 通过切面和注解方式实现的使用 Druid 连接池的动态数据源切换 aspect_dao: 通过切面实现的 DAO 层的动态数据源切换 roundrobin: 通过切面使用轮询方式实现的只读数据源负载均衡...在使用的过程中基本踩遍了所有动态数据源切换的坑,将常见的一些坑和解决方法写在了 Issues 里面 该项目使用了一个可写数据源和多个只读数据源,为了减少数据库压力,使用轮循的方式选择只读数据源;考虑到在一个...Service 中同时会有读和写的操作,所以本应用使用 AOP 切面通过 DAO 层的方法名切换只读数据源;但这种方式要求数据源主从一致,并且应当避免在同一个 Service 方法中写入后立即查询,如果必须在执行写入操作后立即读取...表中的数据,同时也可以在看到切换数据源的 log,说明动态切换数据源是有效的 注意 在该应用中因为使用了 DAO 层的切面切换数据源,所以 @Transactional 注解不能加在类上,只能用于方法
来源 | https://www.cnblogs.com/cjsblog/p/9712457.html 1、引言 读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿...这里我们选择程序自己来做,主要是利用Spring提供的路由数据源,以及AOP 然而,应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点,因为数据源配置都是写在配置中的,新增数据库意味着新加一个数据源...2、AbstractRoutingDataSource 基于特定的查找key路由到特定的数据源。它内部维护了一组目标数据源,并且做了路由key与目标数据源之间的映射,提供基于key查找数据源的方法。...容器中现在有4个数据源,所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。...设置路由key / 查找数据源 目标数据源就是那前3个这个我们是知道的,但是使用的时候是如果查找数据源的呢?
引言 ---- 读写分离要做的事情就是对于一条SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做。因此,一般来讲,读写分离有两种实现方式。...这里我们选择程序自己来做,主要是利用Spring提供的路由数据源,以及AOP 然而,应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点,因为数据源配置都是写在配置中的,新增数据库意味着新加一个数据源...它内部维护了一组目标数据源,并且做了路由key与目标数据源之间的映射,提供基于key查找数据源的方法。 3....容器中现在有4个数据源,所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。...设置路由key / 查找数据源 目标数据源就是那前3个这个我们是知道的,但是使用的时候是如果查找数据源的呢?
SQL该选择哪个数据库去执行,至于谁来做选择数据库这件事儿,无非两个,要么中间件帮我们做,要么程序自己做。...这里我们选择程序自己来做,主要是利用Spring提供的路由数据源,以及AOP 然而,应用程序层面去做读写分离最大的弱点(不足之处)在于无法动态增加数据库节点,因为数据源配置都是写在配置中的,新增数据库意味着新加一个数据源...2.AbstractRoutingDataSource 基于特定的查找key路由到特定的数据源。它内部维护了一组目标数据源,并且做了路由key与目标数据源之间的映射,提供基于key查找数据源的方法。...容器中现在有4个数据源,所以我们需要为事务管理器和MyBatis手动指定一个明确的数据源。...3.3 设置路由key / 查找数据源 目标数据源就是那前3个这个我们是知道的,但是使用的时候是如果查找数据源的呢?
在读写分离时会不会造成事务主从切换错误 一个线程在Serivcie时Select时选择的是从库,DynamicDataSourceHolder中ThreadLocal对应线程存储的是slave,然后调用...事务管理器 Spring中通常通过@Transactional来声明使用事务。如果@Transactional不指定事务管理器,使用缺省。...transaction-manager属性保存一个对在Spring配置文件中定义的事务管理器bean的引用,如果没有它,就会忽略@Transactional注释,导致代码不会使用任何事务。...注意@Transactional建议在具体的类(或类的方法)上使用,不要使用在类所要实现的任何接口上。...(推荐阅读:数据库事务与MySQL事务总结 https://zhuanlan.zhihu.com/p/29166694) Q1 在读写分离时会不会造成事务主从切换错误 一个线程在Serivcie时Select
下面为了方便分析,以典型的读写分离为例作为讲解~ 读写分离:主库master可读可写,从库slave是readOnly的且可以有多个。 为何数据库需要读写分离?...采用读写分离技术的目标:有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库(多个Slave之间也可实现负载均衡),从而保证整个系统的健壮性。...接下来介绍的这种方式是使用最广泛也是本文的主菜~~~ 方式三:AbstractRoutingDataSource动态切换数据源 在基于三层的后端架构中,操作数据库的是Dao层。...因此下面继续介绍更加优雅的操作方式(自定义注解+AOP) 使用AOP+自定义注解方式优雅的实现数据源动态切换 为了实现更优雅的动态数据源的切换,我们可以使用Spring AOP+自定义注解的方式实现对方法级别的数据源切换...(具体在JTA事务里再会详解) 另外,上面讲述的这些API都在spring-jdbc.jar里。 最后也留一个小悬念:多数据源切换是成功了,但牵涉到事务呢?
上午花了大半天排查一个多数据源主从切换的问题,记录一下: 背景: 项目的数据库采用了读写分离多数据源,采用AOP进行拦截,利用ThreadLocal及AbstractRoutingDataSource进行数据源切换...,其它方法切换到从库。...spring的xml配置如下: 数据源: 1 ...,一直报read-only异常,当时判断应该是连接到从库上了(注:从库是只读权限,无法更新数据),方法伪代码如下: 1 @Transactional 2 void doSomeThing(){ 3 ...xxxMapper.select(...); 4 yyyMapper.update(...); 5 ... 6 } 执行到第4行的时候,死活切换不到master主库上来,哪怕在doSomeThing
基于自定义注解和Aop动态数据源配置 在实际项目中,经常会因为需要增强数据库并发能力而设计分库分表或者读写分离等策略,每在旧项目中引进新技术的时候都会带来一系列的问题,我们的目的就是去解决问题...配置pom.xml,使用的是阿里巴巴数据源包和Mysql 5.1.30的驱动 <!...spring-dispatcher.xml依赖的config.properties配置文件如下: # =====================数据源切换数据master和slave数据库=======...基本核心配置和核心代码已经如上了,那我们要怎么使用了,如spring-dispatcher.xml 配置中配置Aop的切点是service包下的所有方法。...在同一个service方法中由于涉及到二个库的增删改查,但切换数据源注解是配置在service方法上的,所以导致不能自动切换数据源,采用的手手动切换,切换代码如下: DynamicDataSourceHolder.setDataSourceType
数据源切换原理 通过扩展Spring提供的抽象类AbstractRoutingDataSource,可以实现切换数据源。...3.3 方案不足 基于AbstractRoutingDataSource的多数据源动态切换,有个明显的缺点,无法动态添加和删除数据源。在我们的产品中,不能把应用数据源写死在配置文件。...在项目运行过程中,可以使用定时任务对数据源进行保活,为了提升性能再添加一层缓存。 AbstractRoutingDataSource 只支持单库事务,切换数据源是在开启事务之前执行。...借助Spring的声明式事务处理,我们可以在多次切库操作时强制开启新的事务: @SwitchDataSource @Transactional(rollbackFor = Exception.class...1.提到Spring事务,就离不开事务的四大特性和隔离级别、七大传播特性。 事务特性和离级别是属于数据库范畴。Spring事务的七大传播特性是什么呢?
前言 随着业务量的不断增长,数据库的读写压力也越来越大。为了解决这个问题,我们可以采用读写分离的方案来分担数据库的读写负载。...本文将介绍如何使用 Spring Boot + MyBatis Plus + MySQL 实现读写分离。...配置数据源 在 Spring Boot 中,我们可以使用 application.yml 文件来配置数据源。在这里,我们需要配置两个数据源,一个用于主库,一个用于从库。...AOP以注解方式切换只读数据库。...读写分离可以有效地分担数据库的读写负载,提高数据库的性能和可用性。希望本文能对读写分离的实现有所帮助。
主要应用场景如:测试时不重启服务切换数据源,准生产无缝切换生产环境,应用端读写分离策略动态化等等,更多的使用场景欢迎在留言区补充。...实现思路 通过对主流数据源(c3p0,dbcp2,tomcat jdbc,Hikari)实现的代理,来动态管理应用到数据库的连接,以及实现应用端的读写分离数据链接策略。...通过AbstractRoutingDataSource对DataSource的管理,使用apollo配置动态推送能力,动态修改AbstractRoutingDataSource中resolvedDataSources...的环境,spring boot2.0中默认数据库连接池用的Hikari,这个连接池性能不俗,按官方说法,他们在程序基础数据结构,字节码,编译器级别做了大量优化,来保证Hikari的优异性能。...当然,不仅仅是数据库的数据连接可以动态切换,按照上面的设计实现思路,通过apollo的动态配置能力,可以轻松实现很多的线上动态切换。
领取专属 10元无门槛券
手把手带您无忧上云