现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库。Master库负责数据更新和实时数据查询,Slave库当然负责非实时数据查询。因为在实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较少),而读取数据通常耗时比较长,占用数据库服务器的CPU较多,从而影响用户体验。我们通常的做法就是把查询从主库中抽取出来,采用多个从库,使用负载均衡,减轻每个从库的查询压力。

采用读写分离技术的目标:有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库,从而保证系统的健壮性。我们看下采用读写分离的背景。

随着网站的业务不断扩展,数据不断增加,用户越来越多,数据库的压力也就越来越大,采用传统的方式,比如:数据库或者SQL的优化基本已达不到要求,这个时候可以采用读写分离的策略来改变现状。

具体到开发中,如何方便的实现读写分离呢?目前常用的有两种方式:

1.第一种方式是我们最常用的方式,就是定义2个数据库连接,一个是MasterDataSource,另一个是SlaveDataSource。更新数据时我们读取MasterDataSource,查询数据时我们读取SlaveDataSource。这种方式很简单,我就不赘述了。

2.第二种方式动态数据源切换,就是在程序运行时,把数据源动态织入到程序中,从而选择读取主库还是从库。主要使用的技术是:annotation,SpringAOP,反射。

借助于spring框架在2.0.1之后提供的AbstractRoutingDataSource可以实现动态的选择数据源datasource,下面先举一个最简单的例子:

一、首先新建一个CatalogVO对象的DAO(见代码1),它继承了SimpleJdbcDaoSupport,JdbcDaoSupport需要注入一个DataSource,同时也提供了操作模板JdbcTemplate。添加一个方法用于获取所有的“货物Item”。货物Iteam是一个POJO类(见代码2)

代码1:

代码2:

二、配置Spring多数据源,这里配置了一个主库和一个从库,他们可以共同继承一个父的数据源。

代码3:

三、新建一个datasource继承自AbstractRoutingDataSource,并且覆盖determineCurrentLookupKey()方法,每次用这个datasource获取数据库连接的时候都会回调这个方法获得key,根据返回的字符串key(也可以是枚举值,数字类型),动态地通过datasource配置的id来在Spring的配置文件中找到相应的datasource来获取connection(见代码4)。那么如果每次访问都需要根据key来决定如何选择数据源,那么这个key必须要保证线程安全,并发情况下每个线程都会去寻找本应该属于自己的key获取数据源,所以CustomerContextHolder类中就用到了ThreadLocal来保证(见代码5)。

代码4:

代码5:

在Spring中的配置如下:

代码6:

四、测试用例

代码7:

为了方便测试,另外定义了2个数据库,shop模拟Master库,test模拟Slave库,shop和test的表结构一致,但数据不同,数据库配置如下:

在spring的配置中增加aop配置

下面是MyBatis的UserMapper的定义,为了方便测试,登录读取的是Master库,用户列表读取Slave库:

好了,运行我们的Eclipse看看效果,输入用户名admin登录看看效果

从图中可以看出,登录的用户和用户列表的数据是不同的,也验证了我们的实现,登录读取Master库,用户列表读取Slave库。

小编结语:

更多内容尽在课课家教育~~

spring mysql 读写分离_如何利用Spring实现数据库读写分离?相关推荐

  1. jfinal mysql读写分离_在JFinal中对数据库读写分离的实现:报错 -问答-阿里云开发者社区-阿里云...

    频繁使用 use(configName) 没有任何性能问题,仅仅是为变量赋一个 string 值而已,完全可以忽略######@JFinal######我现在也使用,读用的是视图model,写操作使用 ...

  2. mysql读写分离java配置方法_springboot配置数据库读写分离

    为什么要做数据库读写分离 大多数互联网业务,往往读多写少,这时候,数据库的读会首先称为数据库的瓶颈,这时,如果我们希望能够线性的提升数据库的读性能,消除读写锁冲突从而提升数据库的写性能,那么就可以使用 ...

  3. .net core发布 正在发现数据上下文_使用EF Core实现数据库读写分离

    以下文章来源于朝夕Net社区 ,作者Eleven 朝夕Net社区 朝气.丰富.活跃的.Net社区,朝夕教育携百万粉丝共同打造!有技术,有感悟,有新闻,有照片,有故事,还有梦想! [精选转载]| 作者/ ...

  4. 小马哥spring编程核心思想_小马哥讲Spring核心编程思想

    小马哥讲Spring核心编程思想 ├─第01章:Spring Framework总览 (12讲) │      01丨课程介绍.mp4 │      02丨内容综述.mp4 │      03丨课前准 ...

  5. php读写分离数据不能同步,thinkphp 下数据库读写分离代码剖析

    当采用原生态的sql语句进行写入操作的时候,要用execute,读操作要用query. MySQL数据主从同步还是要靠MySQL的机制来实现,所以这个时候MySQL主从同步的延迟问题是需要优化,延迟时 ...

  6. 建站助手配置mysql远程权限_建站助手设置数据库

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  7. mysql slave 配置_【mysql5.6】 数据库主从(Master/Slave)配置记录

    freddon 发表于2018-04-01 阅读 661 | 评论 0 前一段时间迫于服务器的捉急内存,将redis数据库停掉了,鉴于redis的主从配置,在centos配置下mysql记录下过程. ...

  8. spring手动控制事务开启_“上帝视角”图解Spring事务的传播机制原理

    转载:https://mp.weixin.qq.com/s/odP1DKgRtXsCcAKxwGahug 数据库事务的"抓手" 数据库的事务功能已经由数据库自身实现,它留给用户的就 ...

  9. spring-mybatis.xml 访问html5,Spring mvc无xml配置及利用JdbcTemplate访问数据库

    项目结构 一.新建动态web项目取名HelloSpringMVC 二./WebContent/WEB-INF/lib下导入必要依赖库 commons-collections4-4.1.jar.comm ...

最新文章

  1. 自定义算子高性能开发
  2. python读取excel-python 读取 Excel
  3. 关于TP-LINK宽带路由器上的“转发规则”功能用途及设置办法
  4. HashSet集合存储数据的结构(哈希表)及set集合存储元素不重复的原理
  5. java实现的小程序_Java实现 微信小程序 + 消息推送
  6. 从Java转向.NET/C#,Are You OK?
  7. linux之head命令
  8. 【HDU - 2717】【POJ - 3278】Catch That Cow (经典bfs,类似dp)
  9. 链表(单链表、双链表、内核链表)
  10. JS数据结构与算法——选择排序(把小的数字依次往前放)
  11. hp虚拟服务器,源自基础设施灵活多变的终极自由 惠普(HP)虚拟连接技术(Virtual Connect)...
  12. android 点餐系统 构思
  13. 计算机网络科研项目申请书,科研项目申请书范文例.doc
  14. 一切成功源于积累——20140928 认识货币——加元
  15. 利用python破解zip压缩文件密码
  16. html中calc属性什么意思,CSS3中新属性calc()的详细介绍
  17. Android 防止App退出 或者 启动另一个App
  18. 生信学习入门常见错误可能的原因分类总结和求助指南
  19. 安卓实战:自定义软键盘 (2)
  20. seo日常工作表_seo专员日常工作内容是什么?

热门文章

  1. 分析flv文件的信息
  2. 高性能、高并发、高扩展性和可读性的网络服务器架构:StateThreads
  3. 显卡欺骗器状态检测及安装注意事项
  4. TensorFlow 1.2正式发布,新增Python 3.6支持
  5. DevOps发展的9个趋势
  6. centos7 redis5.0以前版本 部署集群示例 - 第二篇
  7. 用 Flink 取代 Spark Streaming,知乎实时数仓架构演进【推荐】
  8. hive插入数据:FAILED: ParseException line 1:12 missing TABLE at 'student' near 'EOF'
  9. 数据结构:超好用的数据结构与算法可视化工具(USFCA旧金山大学)
  10. 数据结构:(翻转二叉树) 若二叉树采用二叉链表作存储结构,要交换其所有分支结点的左右子树的位置,采用()遍历方法最合适