关于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。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了