springboot配置多数据源以及事务问题

一、背景以及为什么需要学习

在高并发的项目中,单数据库已无法承载大数据量的访问,因此需要使用多个数据库进行对数据的读写分离,此外就是在微服化的今天,我们在项目中可能采用各种不同存储,因此也需要连接不同的数据库,居于这样的背景,这里简单分享实现的思路以及实现方案

二、实现方式

多数据源实现思路有两种,一种是通过配置多个SqlSessionFactory实现多数据源;

1、通过配置多个SqlSessionFactory实现多数据源在这里插入图片描述

2、通过Spring提供的AbstractRoutingDataSource抽象了一个DynamicDataSource实现动态切换数据源

在这里插入图片描述

三、方式一:不同库的Mapper指定不同的SqlSessionFactory

1 针对不同的库分别放置对用不同的SqlSessionFactory

UserDataSourceConfiguration

@Configuration
@MapperScan(basePackages = "org.datasource.demo1.usermapper",sqlSessionFactoryRef = "userSqlSessionFactory")
public class UserDataSourceConfiguration {public static final String MAPPER_LOCATION = "classpath:usermapper/*.xml";@Primary@Bean("userDataSource")@ConfigurationProperties(prefix = "spring.datasource.user")public DataSource userDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "userTransactionManager")@Primarypublic PlatformTransactionManager userTransactionManager(@Qualifier("userDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Primary@Bean(name = "userSqlSessionFactory")public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(dataSource);sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(UserDataSourceConfiguration.MAPPER_LOCATION));return sessionFactoryBean.getObject();}}

SoulDataSourceConfiguration

@Configuration
@MapperScan(basePackages = "org.datasource.demo1.soulmapper",sqlSessionFactoryRef = "soulSqlSessionFactory")
public class SoulDataSourceConfiguration {public static final String MAPPER_LOCATION = "classpath:soulmapper/*.xml";@Bean("soulDataSource")@ConfigurationProperties(prefix = "spring.datasource.soul")public DataSource soulDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "soulTransactionManager")public PlatformTransactionManager soulTransactionManager(@Qualifier("soulDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}@Bean(name = "soulSqlSessionFactory")public SqlSessionFactory soulSqlSessionFactory(@Qualifier("soulDataSource") DataSource dataSource) throws Exception {final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(dataSource);sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(SoulDataSourceConfiguration.MAPPER_LOCATION));return sessionFactoryBean.getObject();}}

2 使用和测试

@Service
public class AppAuthService {@Autowiredprivate AppAuthMapper appAuthMapper;@Transactional(rollbackFor = Exception.class)public int getCount() {int a = appAuthMapper.listCount();int b = 1 / 0;return a;}}@SpringBootTest
@RunWith(SpringRunner.class)
public class TestDataSource {@Autowiredprivate AppAuthService appAuthService;@Autowiredprivate SysUserService sysUserService;@Testpublic void test_dataSource1(){int b=sysUserService.getCount();int a=appAuthService.getCount();}
}

3 总结

此种方式使用起来分层明确,不存在任何冗余代码,不足地方就是每个库都需要对应一个配置类,该配置类中实现方式都基本类似,该种解决方案每个配置类中都存在事务管理器,因此不需要单独再去额外的关注。在使用时需要指定事务管理器

四、AOP+自定义注解

关于采用Spring AOP方式实现原理就是把多个数据源存储在一个 Map中,当需要使用某个数据源时,从 Map中获取此数据源进行处理。
在这里插入图片描述

1 AbstractRoutingDataSource

在Spring中提供了AbstractRoutingDataSource来实现此功能,继承AbstractRoutingDataSource类并覆写其determineCurrentLookupKey()方法就可以完成数据源切换,该方法只需要返回数据源key即可,也就是存放数据源的Map的key,接下来我们来看一下AbstractRoutingDataSource整体的继承结构,看他是如何做到的。
在这里插入图片描述
在整体的继承结构上我们会发现AbstractRoutingDataSource最终是继承于DataSource,因此当我们继承AbstractRoutingDataSource是我们自身也是一个数据源,对于数据源必然有连接数据库的动作,如下代码:

public Connection getConnection() throws SQLException {return this.determineTargetDataSource().getConnection();
}public Connection getConnection(String username, String password) throws SQLException {return this.determineTargetDataSource().getConnection(username, password);
}

只是AbstractRoutingDataSource的getConnection()方法里实际是调用determineTargetDataSource()返回的数据源的getConnection()方法。

protected DataSource determineTargetDataSource() {Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");Object lookupKey = this.determineCurrentLookupKey();DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey);if (dataSource == null && (this.lenientFallback || lookupKey == null)) {dataSource = this.resolvedDefaultDataSource;}if (dataSource == null) {throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");} else {return dataSource;}
}

该方法通过determineCurrentLookupKey()方法获取一个key,通过key从resolvedDataSources中获取数据源DataSource对象。determineCurrentLookupKey()是个抽象方法,需要继承AbstractRoutingDataSource的类实现;而resolvedDataSources是一个Map<Object, DataSource>,里面应该保存当前所有可切换的数据源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

点亮城市名片丨计讯物联智慧灯杆系统在通讯基地的成功应用

项目背景 在国家新型城镇化大背景下&#xff0c;十四五规划纲要强调“加快数字化发展&#xff0c;建设数字中国”&#xff0c;明确提出“以数字化助推城乡发展和治理模式创新”&#xff0c;全面提高城市的运行效率和宜居程度。 项目概况 为满足灯杆灯光亮度的远程智能管理、对…

记录 android studio 通过安装NDK 编译C文件,得到需要的so文件

只怪自己太健忘&#xff0c;每次网上查了一圈&#xff0c;搞定后&#xff0c;再遇到又发现不会操作了&#xff0c;特此记下 不废话直接上步骤 &#xff08;1&#xff09; 进入AS的settinging如下界面 &#xff08;2&#xff09;选中图片箭头两个文件 进行下载 &#xff08;…

web学习笔记(二十一)

目录 1.构造函数创建对象 1.1规则 1.2 new关键字调用构造函数时&#xff0c;函数内部做了什么事情&#xff1f; 1.3总结 2.混合模式创建对象 3.JavaScript 继承---借助构造函数 4.原型链 4.1原型链实现方法继承 5.完美的组合继承 6.call方法的使用 1.构造函数创建对象…

React之数据绑定以及表单处理

一、表单元素 像<input>、<textarea>、<option>这样的表单元素不同于其他元素&#xff0c;因为他们可以通过用户交互发生变化。这些元素提供的界面使响应用户交互的表单数据处理更加容易 交互属性&#xff0c;用户对一下元素交互时通过onChange回调函数来监听…

回溯例题(leetcode17/37)

文章目录 leetcode37leetcode17 回溯跟枚举差不多。要注意“回溯”&#xff0c;别忘记“回”之前把之前的改动都复原。 leetcode37 leetcode37是解数独问题。本题保证有且仅有唯一解。 思路&#xff1a;先把空格子的位置存下来&#xff0c;然后对每一个空位置挨个枚举1-9。枚…

Excel常用公式总结非常实用

16个最实用的Excel万能公式 1、多条件判断 IF(And(条件1,条件2..条件N),条件成立返回值) IF(or(条件1,条件2..条件N),条件成立返回值) 2、多条件查找 Lookup(1,0/((条件1*条件2*...条件N)),返回值区域&#xff09; 3、多条件求和 Sumifs(值区域,判断区域1,条件1,判断区域2,条…

2024最新精华版Java面试题之spring篇

目录 一、Java面试题之spring篇 1、什么是spring? 2、你们项目中为什么使用Spring框架&#xff1f; 3、 Autowired和Resource关键字的区别&#xff1f; 4、依赖注入的方式有几种&#xff0c;各是什么? 5、讲一下什么是Spring容器&#xff1f; 6、说说你对Spring MVC的理…

Java毕业设计-基于springboot开发的私人健身与教练预约系统-毕业论文+答辩PPT(有源代码)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台功能模块2.1管理员功能2.2用户功能2.3教练功能 四、毕设内容和源代码获取总结 [Java毕业设计-基于springboot…

简单数据类型和复杂数据类型

1. 简单数据类型 null是个特例: 2. 复杂数据类型 3. 堆和栈 注意&#xff1a; JavaScript 中是没有堆和栈的概念的&#xff0c;通过堆栈的概念可以更好的理解代码的一些执行方式&#xff0c;便于将来学习其他语言。 4. 简单数据类型传参 总结&#xff1a;简单数据类型传参传…

在线ai写作,让你随时随地创作优质内容

如今的ai技术已经渗透到我们生活的方方面面。其中&#xff0c;AI写作成为了一个备受关注的领域。如今&#xff0c;我们可以利用在线ai写作在任何时间、任何地点创作出优质的内容。 传统的写作过程需要大量的时间和精力。从构思到写作再到修改&#xff0c;每一个环节都需要我们投…

Linux进程管理——top字段

目录 1.top下半部分——进程状态 2.top常用内部命令 3.top指定 ①top ②top -d 1 ③top -d 1 -p 10126 ④top -d 1 -p 10126,1 4.使用信号控制进程 1.top下半部分——进程状态 PID&#xff1a;进程号 User&#xff1a;用户 PR/NI&#xff1a;优先级 VIRT&#xff08…

国产软件很流氓?不,这些国产软件良心且实用,别让它们寒心

谈及国产软件&#xff0c;人们常将其与“流氓、捆绑、满屏广告”等负面词汇挂钩。但真实情况是&#xff0c;仍有许多优质国产软件在默默耕耘&#xff0c;它们既免费又实用&#xff0c;别让它们寒了心。 1、Dism Dism是一款专为Windows系统设计的管理优化神器&#xff0c;其开…

呦呵,阿里云果然是良心云

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 你听说了吗?阿里云全线降价20%&#xff0c;还上了热搜。2024年一开年&#xff0c;看来阿里云杀红了眼&#xff0c;云市场即将变天。 现在续费的阿里云主机&#xff0c;续费三年和续费两年的价钱差不多&#xff0…

更先进的功能,无注意力大模型Eagle7B:基于RWKV,推理成本降低10-100 倍,另一个工具包使得大模型推理性能加速达40倍(附详细代码使用举例)

更先进的功能,无注意力大模型Eagle7B:基于RWKV,推理成本降低10-100 倍,另一个工具包使得大模型推理性能加速达40倍(附详细代码使用举例)。 在 AI 赛道中,与动辄上千亿参数的模型相比,最近,小模型开始受到大家的青睐。比如法国 AI 初创公司发布的 Mistral-7B 模型,其…

摄像头工程师说 Camera - 颜色空间 YUV 与 YCbCr 的区别与联系(4)

摄像头工程师说 Camera - 数据格式 YUV 与 YCbCr 的区别与联系&#xff08;4&#xff09; 概述 上回书咱们说到 摄像头工程师说 Camera - 数据格式 YUV 格式的存储&#xff08;3&#xff09; 本节咱们说说YUV 与 YCbCr 两种色彩空间定义的联系与区别。 相同点&#xff1a; Y…

MySQL基础(三)

文章目录 MySQL基础&#xff08;三&#xff09;1. 多表查询1.1 概述1.1.1 数据准备1.1.2 介绍1.1.3 分类 1.2 内连接1.3 外连接1.4 子查询1.4.1 介绍1.4.2 标量子查询1.4.3 列子查询1.4.4 行子查询1.4.5 表子查询 1.5 案例 2. 事务2.1 介绍2.2 操作2.3 四大特性 3. 索引3.1 介绍…

Java-常用集合

Jva常用集合 一、Java 集合框架体系二、Collection接口和方法1. List接口List 接口主要实现类&#xff1a;ArrayListList 的实现类之二&#xff1a;LinkedListList 的实现类之三&#xff1a;Vector 2. Set接口Set 主要实现类&#xff1a;HashSetSet 实现类之二&#xff1a;Link…

HCIA-Datacom实验指导手册:7 构建简单 IPv6 网络

HCIA-Datacom实验指导手册&#xff1a;7 构建简单 IPv6 网络 一、实验介绍&#xff1a;二、实验拓扑&#xff1a;三、实验目的&#xff1a;四、配置步骤&#xff1a;步骤 1 设备基础配置设备命名 步骤 2 配置设备及接口 IPv6 功能步骤 3 配置接口的 link-local 地址&#xff0c…

《C++进阶--10.多态》

目录 10. 多态 10.1 多态的基本概念 10.2 多态案例一-计算器类 10.3 纯虚函数和抽象类 10.4 多态案例二-制作饮品 10.5 虚析构和纯虚析构 10.6 多态案例三-电脑组装 10. 多态 10.1 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静态多态: 函数重载 和 运算…

全网爆火的 MBTI 测试,是隐藏的割韭菜工具?

小伙伴们&#xff0c;谁能想到&#xff0c;作为一名冲浪老手&#xff0c;果子在网上又被骗了。 事情是这样的&#xff0c;前几天&#xff0c;我刷微博&#xff0c;看到一个推荐&#xff0c;大概如下图&#xff0c;是一个 MBTI 人格测试。 MBTI 测试&#xff0c;果子早就做过了…