Spring AOP实现Mysql数据库主从切换(一主多从)
Posted 玉不琢,不成器;人不学,不知道
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP实现Mysql数据库主从切换(一主多从)相关的知识,希望对你有一定的参考价值。
设置数据库主从切换的原因:数据库中经常发生的是“读多写少”,这样读操作对数据库压力比较大,通过采用数据库集群方案,
一个数据库是主库,负责写;其他为从库,负责读,从而实现读写分离增大数据库的容错率。
那么,对数据库的要求是:
1. 读库和写库的数据一致;
2. 写数据必须写到写库;
3. 读数据必须到读库;
Spring AOP实现mysql数据库主从切换的过程:在进入Service之前,使用AOP来做出判断,是使用写库还是读库,判断依据可以根据方法名判断,比如说以"update", "insert", "delete", "save"开头的就走写库,其他的走读库。
实现主从(一主多从)分离:
首先配置主从数据库
主程序启动过程中,通过配置文件将主从数据库的URL以及用户名密码加载到内存中:
AOP切入点的实现:
保证每个线程用到的是自己的数据源,使用ThreadLocal来防止并发带来的问题:
对数据库的主从切换进行调试,最好是分别使用SELECT,UPDATE来调试:
下面的代码是一主多从配置文件的详细解释,而与一主一从的区别在于,一主一从的配置都在数据源配置中完成:
参考链接:https://blog.csdn.net/zbw18297786698/article/details/54343188
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--声明:各DataSource的name 及 MapperScannerConfigurer的name,不要随意更改,否则会影响AOP的读写分离正常使用--> <bean id="parentDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${jdbc-driver}"/> <property name="url" value="${jdbc-url-restaurant}"/> <property name="username" value="${jdbc-user-restaurant}"/> <property name="password" value="${jdbc-password-restaurant}"/> <property name="filters" value="stat"/> <!-- 连接池最大数量 --> <property name="maxActive" value="20"/> <!-- 初始化连接大小 --> <property name="initialSize" value="1"/> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="5000"/> <!-- 连接池最小空闲 --> <property name="minIdle" value="1"/> <property name="timeBetweenEvictionRunsMillis" value="3000"/> <property name="minEvictableIdleTimeMillis" value="180000"/> <property name="validationQuery" value="SELECT ‘x‘ FROM DUAL"/> <property name="testWhileIdle" value="true"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <property name="poolPreparedStatements" value="false"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/> <!-- 超过时间限制是否回收 --> <property name="removeAbandoned" value="true"/> <!-- 超时时间;单位为秒。300秒=5分钟 --> <property name="removeAbandonedTimeout" value="300"/> <!-- 关闭abanded连接时输出错误日志 --> <property name="logAbandoned" value="true"/> <!--<property name="connectionInitSqls" value="set names utf8mb4;"/>--> </bean> <!--动态获取数据库--> <bean id="dsRestaurant_master" parent="parentDataSource"> <property name="url" value="${jdbc-url-restaurant}"/> <property name="username" value="${jdbc-user-restaurant}"/> <property name="password" value="${jdbc-password-restaurant}"/> </bean> <!--restaurant数据源--> <bean id="dsRestaurant" class="cn.mwee.service.shop.lookup.CustomRoutingDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <!--写库--> <entry key="master" value-ref="dsRestaurant_master"/> </map> </property> <property name="defaultTargetDataSource" ref="dsRestaurant_master"/> </bean> <!--restaurant库--><!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --> <bean id="sqlSessionFactoryRestaurant" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:mybatis-config.xml"></property> <property name="dataSource" ref="dsRestaurant"/> <!-- 自动扫描mapping.xml文件 --> <property name="mapperLocations"> <array> <value>classpath:mybatis/restaurant/*.xml</value> </array> </property> </bean> <!-- Mapper接口所在包名,Spring会自动查找其下的类 --> <bean id="restaurantScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.mwee.service.shop.mapper.restaurant"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryRestaurant"/> </bean> <!--事务管理--> <bean id="restaurantTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dsRestaurant"/> </bean> <tx:annotation-driven transaction-manager="restaurantTxManager"/> <!--AOP切面设置 --> <bean id="masterSlaveAspect" class="cn.mwee.service.shop.util.MasterSlaveAspect"/> <aop:config> <aop:aspect ref="masterSlaveAspect" order="1"> <aop:pointcut id="masterSlave" expression="this(tk.mybatis.mapper.common.Mapper)"/> <aop:before pointcut-ref="masterSlave" method="doBefore"/> </aop:aspect> </aop:config> </beans>
以上是关于Spring AOP实现Mysql数据库主从切换(一主多从)的主要内容,如果未能解决你的问题,请参考以下文章
使用Spring AOP实现MySQL数据库读写分离案例分析
spring学习笔记(19)mysql读写分离后端AOP控制实例