spring学习笔记(19)mysql读写分离后端AOP控制实例

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: <div class="markdown_views"><p>在这里,我们接上一篇文章,利用JNDI访问应用服务器配置的两个数据源来模拟同时操作不同的数据库如同时操作mysql和oracle等。实际上,上个例子可能用来模拟mysql数据库主从配置读写分离更贴切些。既然如此,在本例中,我们就完成读写分离的模拟在web端的配置实例。</p><p>续上次的例子,关于JNDI数据

在这里,我们接上一篇文章,利用JNDI访问应用服务器配置的两个数据源来模拟同时操作不同的数据库如同时操作mysql和oracle等。实际上,上个例子可能用来模拟mysql数据库主从配置读写分离更贴切些。既然如此,在本例中,我们就完成读写分离的模拟在web端的配置实例。

续上次的例子,关于JNDI数据源的配置和spring datasource的配置这里不再重复。下面着重加入AOP实现DAO层动态分库调用。可先看上篇文章《spring学习笔记(18)使用JNDI模拟访问应用服务器多数据源实例 》

1. DAO层设计

/***************接口设计************/
public interface MyBaseDao {
    SessionFactory getSessionFactory();
    <E> E add(Object object);
    <E>E queryUnique(Class<E> clazz, Integer entityId);
    void setSourceType(Integer sourceType);
}
/****************实现类设计******************/
@Repository
public class MyBaseDaoImpl implements MyBaseDao{
    //由于本类是单例了,考虑到线程安全问题,这是使用ThreadLocal作为判断调用哪个数据源的依据
    private ThreadLocal<Integer> sourceType = new ThreadLocal<Integer>();
    @Autowired
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;

    @Autowired
    @Qualifier("sessionFactory2")
    private SessionFactory sessionFactory2;

    @Override
    public SessionFactory getSessionFactory() {
        if(sourceType.get() == null){//如果没有值则默认使用数据源1
            sourceType.set(1);
        }
        switch (sourceType.get()) {
        case 1://使用数据源1,本例中这里是主库,主要负责写
            return sessionFactory;
        case 2: //使用数据源2,本例中这里是从库,主要负责读
            return sessionFactory2;
        default:
            throw new IllegalArgumentException("unknown sourceType");
        }
    }
    @Override//模拟一个写的操作,要让主库数据源调用
    public <E> E add(Object object) {
        return (E) getSessionFactory().openSession().save(object);
    }
    @Override//模拟一个读的操作,要让从库数据源调用
    public <E> E queryUnique(Class<E> clazz, Integer entityId) {
        return (E) getSessionFactory().openSession().get(clazz, entityId);
    }
    @Override//共AOP增强类修改数据源类型
    public void setSourceType(Integer sourceType) {
        this.sourceType.set(sourceType);
    }
}

2. AOP类设计

@Aspect
public class DataSourceSelector {//使用前置增强
    @Before("execution( * com.yc.dao.MyBaseDaoImpl.add*(..))")//写操作
    public void before1(JoinPoint joinPoint){
        ((MyBaseDao)joinPoint.getTarget()).setSourceType(1);//切换到主库
    }

    @Before("execution( * com.yc.dao.MyBaseDaoImpl.query*(..))")//读操作
    public void before2(JoinPoint joinPoint){
        ((MyBaseDao)joinPoint.getTarget()).setSourceType(2);//切换到从库
    }
}

关于AOP的配置教程,可移步参考本系列前面AOP部分的文章。然后我们还需要在IOC容器中注册我们的切面。

<aop:aspectj-autoproxy />   <!-- 使@AspectJ注解生效 -->
<bean class="com.yc.aop.DataSourceSelector" /><!-- 注册切面 -->

3. 修改控制器

针对上一篇文章的控制器,作如下修改:

@Controller
public class JNDITestController {

    @Autowired
    private MyBaseDao myBaseDao;

    @RequestMapping("testJNDI")
    @ResponseBody
    public Object testJNDI(){
        User user = new User();
        user.setName("new_user_fron_yc1");
        Integer newId = myBaseDao.add(user);
        System.out.println("new UserId = " + newId);//获取我们新插入的id
        System.out.println("is new User here? " + myBaseDao.queryUnique(com.yc.model2.User.class, newId));
        return newId;
    }
}

4. 测试与结果分析

运行服务器,然后在游览器中输入http://localhost:8090/yc/testJNDI,我们会看到控制台打印信息:

new UserId = 4
is new User here? null

newUserId是我们插入到主库中的,id为4。
但我们紧接着读取,却并未读取到。这说明我们存的数据库和读的数据库并不是同一个,从而简单地实现了读写分离。为了验证这一点,我们所示数据库,如下图所示,显然我们在yc1存进去了我们的测试数据,在yc2中并没有!
这里写图片描述

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
4月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
4月前
|
存储 弹性计算 关系型数据库
如何通过控制台创建RDS MySQL实例
本文介绍了通过控制台创建RDS MySQL实例的详细步骤,包括准备工作、选择计费方式、地域、实例规格、存储空间等关键配置,并指导用户完成下单与实例查看。
|
5月前
|
存储 关系型数据库 MySQL
【赵渝强老师】MySQL数据库的多实例环境
MySQL多实例是指在一台服务器上运行多个MySQL服务,通过不同端口提供独立的数据服务。各实例共享安装程序,但使用各自的配置文件和数据文件,实现资源高效利用。本文详细介绍了如何通过“mysqld_multi”工具配置和启动多个MySQL实例,并演示了目录创建、初始化、配置文件修改及实例启动等操作步骤。
243 1
|
8月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
444 41
|
8月前
|
开发框架 Java 关系型数据库
在Linux系统中安装JDK、Tomcat、MySQL以及部署J2EE后端接口
校验时,浏览器输入:http://[your_server_IP]:8080/myapp。如果你看到你的应用的欢迎页面,恭喜你,一切都已就绪。
561 17
|
8月前
|
Java 关系型数据库 MySQL
在Linux操作系统上设置JDK、Tomcat、MySQL以及J2EE后端接口的部署步骤
让我们总结一下,给你的Linux操作系统装备上最强的军队,需要先后装备好JDK的弓箭,布置好Tomcat的阵地,再把MySQL的物资原料准备好,最后部署好J2EE攻城车,那就准备好进军吧,你的Linux军团,无人可挡!
179 18
|
8月前
|
关系型数据库 MySQL Java
安装和配置JDK、Tomcat、MySQL环境,以及如何在Linux下更改后端端口。
遵循这些步骤,你可以顺利完成JDK、Tomcat、MySQL环境的安装和配置,并在Linux下更改后端端口。祝你顺利!
506 11
|
8月前
|
开发框架 关系型数据库 Java
Linux操作系统中JDK、Tomcat、MySQL的完整安装流程以及J2EE后端接口的部署
然后Tomcat会自动将其解压成一个名为ROOT的文件夹。重启Tomcat,让新“植物”适应新环境。访问http://localhost:8080/yourproject看到你的项目页面,说明“植物”种植成功。
252 10
|
9月前
|
SQL Oracle 关系型数据库
在MySQL Shell里 重启MySQL 8.4实例
在MySQL Shell里 重启MySQL 8.4实例
284 2
|
9月前
|
监控 Java 关系型数据库
Spring Boot整合MySQL主从集群同步延迟解决方案
本文针对电商系统在Spring Boot+MyBatis架构下的典型问题(如大促时订单状态延迟、库存超卖误判及用户信息更新延迟)提出解决方案。核心内容包括动态数据源路由(强制读主库)、大事务拆分优化以及延迟感知补偿机制,配合MySQL参数调优和监控集成,有效将主从延迟控制在1秒内。实际测试表明,在10万QPS场景下,订单查询延迟显著降低,超卖误判率下降98%。
413 5

推荐镜像

更多