关于AOP-实现读写分离和事务配置
概念
读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
为什么要实现读写分离
对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
用AOP来实现读写分离
1】导入依赖
2】application.yml中自定义数据源配置项
3】配置Druid
4】配置Mybaits
5】定义一些类实现数据源路由中介、全局数据源
6】编写切面类 ( 拦截读写来动态设置数据源 )
package com.qiang.config.aop; import com.qiang.config.db.DataSourceContextHolder; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * 拦截数据库读写 * * @author gengqiang */ @Aspect @Component @Order(1) public class DataSourceAspect { Logger logger = LoggerFactory.getLogger(getClass()); @Before("execution(* com.qiang..*.*ServiceImpl.find*(..)) " + "|| execution(* com.qiang..*.*ServiceImpl.count*(..))" + "|| execution(* com.qiang..*.*ServiceImpl.sel*(..))" + "|| execution(* com.qiang..*.*ServiceImpl.get*(..))" ) public void setReadDataSourceType() { logger.debug("拦截[read]方法"); DataSourceContextHolder.read(); } @Before("execution(* com.qiang..*.*ServiceImpl.insert*(..)) " + "|| execution(* com.qiang..*.*ServiceImpl.save*(..))" + "|| execution(* com.qiang..*.*ServiceImpl.update*(..))" + "|| execution(* com.qiang..*.*ServiceImpl.set*(..))" + "|| execution(* com.qiang..*.*ServiceImpl.del*(..))") public void setWriteDataSourceType() { logger.debug("拦截[write]操作"); DataSourceContextHolder.write(); } }
配置事物
第一步需要加一个注解@EnableTransactionManagement,后面的参数是为了区分aop和事物执行的顺序。
然后在需要会滚的方法上加一个注解@Transactional。