SpringBoot切换数据源

news2025/1/17 21:44:14

基本使用

  1. 添加依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.3.0</version>
</dependency>
  1. 数据源配置

spring:
  datasource:
    dynamic:
      primary: first #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        first:
          url: jdbc:mysql://localhost:3306/xxx?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&userSSL=false
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: xxx
          password: xxx
        second:
          url: jdbc:mysql://localhost:3306/xxx?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&userSSL=false
          driver-class-name: com.mysql.cj.jdbc.Driver
          username: xxx
          password: xxx
  1. 测试源码

@Select("select * from sms_send_bak limit 10")
@DS("second")
//@Transactional(propagation = Propagation.REQUIRES_NEW)
List<SmsSendBak> list();

@DS("first")
//@Transactional(propagation = Propagation.REQUIRES_NEW)
List<Member> queryMemberByRealName(@Param("realName") String realName);

@Override
//@Transactional(propagation = Propagation.REQUIRES_NEW)
public void testService() {
    List<SmsSendBak> smsSendBaks = smsSendBakMapper.list();
    log.info("smsSendBaks: {}", smsSendBaks);
    List<Member> members = memberMapper.queryMemberByRealName("");
    log.info("members: {}", members);
}

spring事务引起数据源切换失效

失效场景

@Transactional
public void fun() {
 //调用数据源A
 //...
 //调用数据源B
 //...
}//结果:全部调了默认数据源A

原因分析

经查明资料,@Transactional开启会使用默认数据源。事务内切换数据源失效是因为spring检测到事务开启,会将Connection缓存起来,执行每个sql的时候用缓存好的connection,导致数据源切换失效。

解决方案

  1. 外层去掉事务,sql独立使用事务(如果一定要事务);

public void fun() {
    //@Transactional
    //调用数据源A
    //...
    
    //@Transactional
    //调用数据源B
    //...
}
  1. 外层使用默认,里层sql事务设置传播行为:@Transactional(propagation = Propagation.REQUIRES_NEW)

@Transactional
public void fun() {
    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    //调用数据源A
    //...
    
    //@Transactional(propagation = Propagation.REQUIRES_NEW)
    //调用数据源B
    //...
}

由于设置REQUIRES_NEW传播行为,使得每个阶段使用独立的事务来处理,不会使用外层的事务,走外层的数据源。

  1. 里层事务将外层事务挂起(不使用事务,不走外层数据源)

@Transactional
public void fun() {
    //@Transactional(propagation = Propagation.NOT_SUPPORTED)
    //调用数据源A
    //...
    
    //@Transactional(propagation = Propagation.NOT_SUPPORTED)
    //调用数据源B
    //...
}

结论

  1. 不建议在事务内切换数据源,一定要使用事务的话,可以将事务细粒度化

  1. 留意事务的传播行为,当不指定传播行为时,默认的REQUIRES使得被包含的事务共用外层的事务,导致数据源共用外层

  1. 如果一定要外层使用事务,里层方法设置事务传播行为NOT_SUPPORTED来挂起当前事务(外层),这样不会走外层事务的数据源

参考链接:https://blog.51cto.com/u_15501718/5103320

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

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

相关文章

【多元统计分析】Python实现对应分析

&#xff08;一&#xff09;题目要求 数据集包含地区生产总值的四个相关指标&#xff1a;x1劳动者报酬&#xff0c;x2生产税净额&#xff0c;x3固定资产折旧&#xff0c;x4营业盈余。对各个地区生产总值进行对应分析&#xff0c;揭示不同地区的生产总值构成特征。要求&#xf…

对多线程中线程池的理解

一.概念理解何为线程池&#xff1f;线程池的释义正如它的命名&#xff1a;专门用来存放线程的池子&#xff08;集合类&#xff09;&#xff0c;也就是将线程存储于集合类&#xff0c;使用时从线程池中直接获取&#xff0c;使用结束后将线程放回集合类即可&#xff0c;这样就避免…

macOS Ventura 13.2 (22D49) Boot ISO 原版可引导镜像

本站下载的 macOS Ventura 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。 2023 年 1 月 23 日&#xff08;北京时间 24 日凌晨&#xff09;&#xff0c;m…

基于电流型磁链观测器的异步电机矢量控制学习

导读&#xff1a;本期主要介绍电流型磁链观测器&#xff08;current flux observer&#xff09;在不同坐标系下的表现形式&#xff0c;应用在异步电机矢量控制系统中。如需要文中的仿真模型&#xff0c;关注微信公众号&#xff1a;浅谈电机控制&#xff0c;获取。一、引言磁链估…

JavaEE day4 初识HTML+总结3

FORM表单的常见type属性 FORM表单的tpye属性非常多&#xff0c;这里只介绍常见的几个&#xff1a; text &#xff1a; 输入普通文本&#xff0c;例如登录注册下的用户名 password &#xff1a; 输入密码文本&#xff0c;例如登录注册下的密码&#xff0c;隐藏用户的输入 ra…

如何使用JDBC操作数据库,JDBC实战案例详细解读

1. 前言 前面 3 篇 JDBC 入门级基础文章中&#xff0c;我们已经探讨了什么是 JDBC&#xff0c;如何使用JDBC 操作数据库&#xff0c;JDBC API 详细解读&#xff0c;以及数据库连接池的基础等。文章带来的反馈还不错&#xff0c;今天我们使用前面学习的内容做一个实战案例训练。…

贪心 135. 分发糖果

135. 分发糖果 难度困难1086 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&…

uboot启动流程简要版(基于armv7)

uboot启动流程&#xff08;armv7&#xff09; uboot介绍 uboot就是一段引导程序&#xff0c;在加载系统内核之前&#xff0c;完成硬件初始化&#xff0c;内存映射&#xff0c;为后续内核的引导提供一个良好的环境。 uboot是bootloader的一种&#xff0c;全称为universal boot…

二叉树基础oj练习

1.单值二叉树 题目: 力扣https://leetcode.cn/problems/univalued-binary-tree/ 思路: 单值二叉树 root和左右孩子的值相等 左子树是单值二叉树 右子树是单值二叉树 代码: /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeN…

CSS 艺术之心形-彩虹-加载动画

CSS 艺术之心形-彩虹-加载动画&#xff08;居中抖动问题&#xff09;参考描述效果HTMLCSS重置元素的部分默认样式bodyli动画定义指定animationul居中抖动问题代码总汇参考 项目描述搜索引擎BingMDNMDN Web Docs 描述 项目描述Edge109.0.1518.61 (正式版本) (64 位) 效果 HTML…

【Vue笔记】Vue中默认插槽slot、具名插槽slot、自定义组件的v-model属性的使用

这篇文章&#xff0c;主要介绍Vue中默认插槽slot、具名插槽slot、自定义组件的v-model属性的使用。 目录 一、插槽slot介绍 1.1、默认插槽 1.2、具名插槽 &#xff08;1&#xff09;如何定义具名插槽&#xff1f;&#xff1f;&#xff1f; &#xff08;2&#xff09;如何使…

3DMAX纹理插件BerconMaps使用教程

BerconMaps是3dMax的第三方纹理插件。它添加了五个新的3dMax纹理贴图&#xff1a;噪波&#xff08;Noise&#xff09;、木纹&#xff08;Wood&#xff09;、瓷砖&#xff08;Tile&#xff09;、失真&#xff08;Distortion&#xff09;和渐变&#xff08;Gradient&#xff09;。…

linux配置samba服务

文章目录samba服务第一步&#xff1a;下载samba服务第二步&#xff1a;开启服务&#xff0c;查看服务状态第三步&#xff1a;在文件夹系统查看第四步&#xff1a;设置samba的配置文件第五步&#xff1a;再次去尝试连接linux服务共享修改smab服务的配置设置samba服务的用户名和密…

verilog实现计算器设计

该实验为用verilog编写的一个运算系统,其功能是实现4位整数的加、减、乘、除运算。运算时通过矩阵键盘输入运算类型和运算所需要的数据,然后通过内部电路处理,将计算的结果送于数码管或LCD1602显示。 工程截图如下: 本设计分为两个子模块,按键输入和数码管输出。 还有LC…

python字符串

python字符串 文章目录python字符串一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.字符串创建2.转义字符3.运算符4.格式化5.三引号6.内建函数总结一、实验目的 掌握字符串的用法 二、实验原理 字符串 字符串是一种序列&#xff0c;用于表示和存储文本。py…

Ubuntu16.04安装Chrome出错

安装了Ubuntu16.04之后想要装个Chrome&#xff0c;本来觉得是很简单的事情&#xff0c;下载->安装就结束了&#xff0c;结果没想到搞了好久&#xff0c;最后发现是因为自己偷懒所造成的&#xff01;因此&#xff0c;写下这篇博文做警示&#xff0c;如果其他人也碰到这样的问…

20230124使AIO-3568J开发板在Android12下横屏

20230124使AIO-3568J开发板在Android12下横屏 2023/1/24 14:05 百度搜索&#xff1a;RK3568 强制横屏 http://www.360doc.com/content/12/0121/07/29321110_1049371522.shtml RK3568 Android-HDMI旋转屏幕显示 硬件开发板&#xff1a;OK3568-C开发板&#xff08;基于国产瑞芯微…

【Leetcode每日一题】34.在排序数组中查找元素的第一个和最后一个位置|二分求下标

&#x1f331;博主简介&#xff1a;大一计科生&#xff0c;努力学习Java中!热爱写博客~预备程序媛 &#x1f4dc;所属专栏&#xff1a;LeetCode每日一题–进击大厂 ✈往期博文回顾: 【Leetcode每日一题】35.搜素插入位置|二分查找数组下标 &#x1f575;️‍♂️近期目标&#…

恶意代码分析实战 5 分析恶意Windows程序

1 Lab07-01 本次实验分析lab07-01.exe,lab07-02.exe,先来看lab07-01.exe的问题 问题 计算机重启后&#xff0c;这个程序如何确保它继续运行&#xff08;达到持久化驻留&#xff09; 首先&#xff0c;查看导入函数。 OpenSCManagerA和CreateServiceA函数暗示着这个恶意代码…

蓝队-HTTP协议的分析

文章目录应用层的协议→HTTP协议访问地址web网站的正确访问姿势请求协议https访问的密钥文件网站的部署通过https协议访问请求报文响应报文请求方法http头协议cookiesRefererUser-AgentX-Forwarded-ForHTTP 状态码HTTP content-type抓包分析HTTP抓包代理插件的下载代理第一种方…