点击上方蓝色“方志朋”,选择“设为星标”

回复“666”获取独家整理的学习资料!

作者:青石路

cnblogs.com/youzhibing/p/12671004.html

前情回顾

看着文章的标题,不知道大家能否想到具体是什么问题,如果你有点懵,那就对了!(你不懵的话我这篇文章就没存在的意义了,嘿嘿)

在给大家指出具体是什么问题时,我们先来回顾一些内容

Spring 事务原理

相信大家对这个都能说上来一些,Spring 事务是 Spring AOP 的一种具体应用,底层依赖的是动态代理

大致流程类似如下

通过代理对象来调用目标对象,而在代理对象中有事务相关的增强处理

具体细节可参考以下文章

  • https://www.cnblogs.com/youzhibing/p/6414780.html

  • https://www.cnblogs.com/youzhibing/p/6690341.html

  • https://www.cnblogs.com/youzhibing/p/12071391.html

Spring 动态数据源原理

原理解密 → Spring AOP 实现动态数据源(读写分离),底层原理是什么中已经详细介绍过了,流程大体如下

Spring AOP → 将我们指定的 lookupKey 放入 ThreadLocal

ThreadLocal → 线程内共享 lookupKey

DynamicDataSource → 对多数据源进行封装,根据 ThreadLocal 中的 lookupKey 动态选择具体的数据源

有什么问题

既然事务和动态数据源都是 Spring AOP 的具体应用,那么代理就存在先后顺序了

要么是

要么是

我们来看看这两者有什么区别

事务在前,动态数据源在后

此时,事务的前置增强处理会先生效,那么此时开始事务获取的 Connection 从哪来 ?肯定是从 DynamicDataSource 来,因为我们给事务管理器配置的就是它

    @Beanpublic PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) {// 配置事务管理, 使用事务时在方法头部添加@Transactional注解即可return new DataSourceTransactionManager(dynamicDataSource);}

既然是从 DynamicDataSource 获取的 Connection,那 DynamicDataSource 根据 lookupKey 获取 Connection 的时候,会从 masterDataSource 数据源获取还是从 slaveDataSource 数据源获取 ?因为此时还未将 lookupKey 绑定到当前线程,那么 DynamicDataSource 会从默认数据源获取,而我们配置的默认数据源是 slaveDataSource

    /*** 获取当前线程的数据源* @return*/public static DataSourceType getDataSourceType(){return  HOLDER.get() == null ? DataSourceType.SLAVE : HOLDER.get();}

说白了,此时的动态数据源对事务不生效,事务始终从默认数据源获取 Connection,而没有动态的效果,这就是问题了

Talk is cheap. Show me the code,我们来看看是不是真的如上所说

192.168.0.112 正是我们的从库,对应的就是我们的默认数据源 slaveDataSource

动态数据源在前,事务在后

此时,动态数据源的前置增强会先执行,DynamicDataSource 需要的 lookupKey 会先于事务绑定到当前线程,那么事务从 DynamicDataSource 获取 Connection 的时候就能根据当前线程的 lookupKey 来动态选择 masterDataSource 还是 slaveDataSource

此种情况是没有问题的

解决问题

总结下问题:如何保证事务中的动态数据源也有动态的效果,也就是如何保证动态数据源的前置增强先于事务

我们知道 Spring AOP 是能够指定顺序的,只要我们显示的指定动态数据源的 AOP 先于 事务的 AOP 即可;如何指定顺序,常用的方式是实现 Order 接口,或者使用 @Order 注解,Order 的值越小,越先执行,所以我们只需要保证动态数据源的 Order 值小于事务的 Order 值即可

我们先来看看事务的 Order 值默认是多少,在 EnableTransactionManagement 注解中

    /*** Indicate the ordering of the execution of the transaction advisor* when multiple advices are applied at a specific joinpoint.* <p>The default is {@link Ordered#LOWEST_PRECEDENCE}.*/int order() default Ordered.LOWEST_PRECEDENCE;

默认是最低级别(值非常大),那么我们只需要保证动态数据源的 Order 比这个值小就好,我们就取 1

  @Component@Slf4j@Order(1)public&nbsp;class&nbsp;DynamicDataSourceAspect&nbsp;{

我们在来看看是否真的可行

已经不是默认的 slaveDataSource ,而是我们指定的 masterDataSource(通过 @MasterSlave(MASTER) 指定)

至此,相信大家已经弄清楚了有什么问题,以及如何解决它

什么,还没理解 ?你过来,我保证不打死你

总结

1、不只是动态数据源和事务,只要涉及到多个 AOP,就可能会有顺序问题,这是值得大家注意的

2、相关约束

  • 主数据库执行 INSERT UPDATE DELETE 操作,可能还有部分 SELECT 操作(主从同步多少有延时)

  • 从数据库只执行 SELECT 操作

  • 默认数据源最好设置成主数据源,防止粗心将更新操作执行到了从数据库;楼主之所以设置成从数据源,是考虑到绝大多数数据库操作是查询,这样可以减少代码量;具体怎么选,需要大家结合实际情况来决定

热门内容:
  • 道友自诉:入职中软一个月(外包华为)就离职了!

  • 腾讯推出高性能 RPC 开发框架

  • 再见了SpringMVC,这个框架有点厉害,甚至干掉了Servlet!

  • 原来 Elasticsearch 还可以这么理解

  • 干掉Navicat:正版,MySQL官方客户端真香!

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)

Spring 下,关于动态数据源的事务问题的探讨相关推荐

  1. java多个数据库数据进行访问_通过Spring Boot配置动态数据源访问多个数据库的实现代码...

    之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...

  2. mysql 多数据源访问_通过Spring Boot配置动态数据源访问多个数据库的实现代码

    之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...

  3. Spring(AbstractRoutingDataSource)实现动态数据源切换

    参考:http://linhongyu.blog.51cto.com/6373370/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目A中 ...

  4. Spring(AbstractRoutingDataSource)实现动态数据源切换--转载

    原始出处:http://linhongyu.blog.51cto.com/6373370/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目 ...

  5. Spring Boot使用动态数据源

    文章目录 前言 一.什么是动态数据源 二.动态数据源实现 1.实现原理 2.实现过程 前言 有这样一个场景,现在要开发一个数据API功能,用户自己编写数据源脚本,在界面任意选择一个数据源,可选择的数据 ...

  6. SpringBoot+MyBatis(动态数据源/分布式事务XA(Atomikos))

    快速集成工具,欢迎打脸 说明 适用环境:SpringBoot / MyBatis / Atomickos  特性: 多数据源,动态切换 多数据源,XA分布式事务支持(需引入Atomickos) 仅支持 ...

  7. spring 动态数据源切换实例

    我们很多项目中业务都需要涉及到多个数据源,最简单的做法就是直接在java代码里面lookup需要的数据源,但是这样的做法很明显耦合度太高了, 而且当逻辑流程不够严谨的时候就会出现各种大家不愿意看到的问 ...

  8. spring 动态数据源

    1.动态数据源:  在一个项目中,有时候需要用到多个数据库,比如读写分离,数据库的分布式存储等等,这时我们要在项目中配置多个数据库. 2.原理:   (1).spring 单数据源获取数据连接过程: ...

  9. 我已经把它摸的透透的了!!!Spring 动态数据源设计实践,全面解析

    [ Spring 动态数据源 动态数据源是什么?它能解决什么??? 在实际的开发中,同一个项目中使用多个数据源是很常见的场景.比如,一个读写分离的项目存在主数据源与读数据源. 所谓动态数据源,就是通过 ...

最新文章

  1. 自定义audio样式
  2. 用InstallShield9打包 vb6+水晶报表中文版9.2 [转]
  3. UVa 10061 How many zero's and how many digits?
  4. 面试题解析:1 Java中switch语句可以作用在enum上的测试
  5. 大数据分析需注意哪些问题
  6. 计算机开放电子书 2016 归档
  7. dell服务器卸载系统,如何通过 iDRAC9 装载和卸载驱动程序包
  8. linux启动tomcat后,浏览器访问不到
  9. 代写品牌故事四步写作方法
  10. jsp实现文件的上传
  11. 呼叫中心系统的基本构成和二次开发思路
  12. Python-股票-图表显示主要财务指标
  13. 甲方、乙方、监理三者之间的关系及其在项目管理过程中的若干事项
  14. 青软集团U+新工科智慧云平台助力西北民族大学编程竞赛成功举办!
  15. MySQL的limit分页,为什么越往后翻越慢,怎么解决?
  16. 12星座的出生年月日性格_出生的人的星座是什么十二星座出生年月日
  17. SpringBoot实现音乐网站解析(支持腾讯、网易、小米、酷狗)
  18. emacs 24安装ecb与cedet
  19. 2021美赛数据分析全网首发(R语言 )
  20. Oracle数据库中stragg()函数,在瀚高数据库中如何替换使用?

热门文章

  1. 数据库管理工具dbeaver
  2. 每日一题题目29:五个数字能组成多少互不重复的四位数
  3. springmvc xml 空模板
  4. Sass (Syntactically Awesome StyleSheets)
  5. 没听说过这些,就不要说你懂并发了,three。
  6. 【怎样写代码】工厂三兄弟之工厂方法模式(五):工厂方法模式扩展
  7. SIFT 特征检测及匹配
  8. 昇思MindSpore1.6发布 AI开发者体验再升级
  9. 融合AI与大数据技术,腾讯教育发布智能作业灯
  10. 完全免费,简化版Plotly推出,秒绘各类可视化图表