国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

SpringBoot 多數據源并存:原理、實踐與動態數據源辨析

開發 前端
在復雜業務系統中,單一數據庫往往難以滿足所有需求:業務數據需要業務庫,管理數據需要理庫。此時讓不同業務對接專屬數據庫的多數據源并存方案,相比需要動態切換的模式,更能避免線程安全風險和事務混亂,成為更穩妥的選擇。

引言

在復雜業務系統中,單一數據庫往往難以滿足所有需求:業務數據需要業務庫,管理數據需要理庫。此時讓不同業務對接專屬數據庫的多數據源并存方案,相比需要動態切換的模式,更能避免線程安全風險和事務混亂,成為更穩妥的選擇。

多數據源并存的底層邏輯

獨立組件的綁定

多數據源并存的本質是為每個數據庫創建一套完整的數據源 - 會話工廠 - 事務管理器獨立鏈路,各鏈路互不干擾,通過包路徑隔離實現業務與數據源的自動關聯。

關鍵組件關系:

  • 一個數據庫 → 一個DataSource(連接池實例)
  • 一個DataSource → 一個SqlSessionFactorySQL會話工廠)
  • 一個SqlSessionFactory → 一個TransactionManager(事務管理器)
  • 一個事務管理器 → 綁定一組特定包下的Mapper接口

與動態數據源的本質差異

很多開發者會混淆多數據源并存動態數據源,兩者核心區別在于是否存在切換邏輯:

  • 多數據源并存:無切換,各數據源長期存活,業務通過包路徑定向調用
  • 動態數據源:有切換,通過ThreadLocal存儲上下文,在同一鏈路中切換不同數據庫連接

簡單總結:多數據源是分工,動態數據源是兼職

實現案例

多數據源配置

spring:
  datasource:
    druid:
      # 業務庫配置
      business:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/business?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
        username: business
        password: business
      # 管理庫
      management:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/management?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
        username: management
        password: management

核心配置類:構建獨立組件鏈路

為每個數據源創建專屬配置類,通過注解指定掃描范圍和組件關聯,確保鏈路隔離。

@Configuration
@MapperScan(basePackages = "com.yian.mapper.business",sqlSessionFactoryRef = "busSqlSessionFactory")
public class BusDataSourceConfig {
    // 業務庫數據源配置
    @Bean(name = "busDataSource")
    @Qualifier("busDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.business")
    public DataSource busDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    // 業務庫JdbcTemplate
    @Bean(name = "busJdbcTemplate")
    public JdbcTemplate busJdbcTemplate(
            @Qualifier("busDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}
@Configuration
@MapperScan(basePackages = "com.yian.mapper.management",sqlSessionFactoryRef = "manSqlSessionFactory")
public class ManDataSourceConfig {

    // 管理庫數據源配置
    @Bean(name = "manDataSource")
    @Qualifier("manDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.management")
    public DataSource manDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    // 管理庫JdbcTemplate
    @Bean(name = "manJdbcTemplate")
    public JdbcTemplate manJdbcTemplate(
            @Qualifier("manDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}
@Configuration
public class MybatisPlusConfig {

    @Bean
    public SqlSessionFactory manSqlSessionFactory(@Qualifier("manDataSource") DataSource manDataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(manDataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath*:/mapper/management/**/*.xml"));
        //map接收返回值值為null的問題,默認是當值為null,將key返回
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setCallSettersOnNulls(true);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }

    @Bean
    public PlatformTransactionManager manTransactionManager(@Qualifier("manDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public TransactionTemplate manTransactionTemplate(@Qualifier("manTransactionManager") PlatformTransactionManager transactionManager) {
        return new TransactionTemplate(transactionManager);
    }

    @Bean
    public SqlSessionFactory busSqlSessionFactory(@Qualifier("busDataSource") DataSource busDataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(busDataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath*:/mapper/business/**/*.xml"));
        //map接收返回值值為null的問題,默認是當值為null,將key返回
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setCallSettersOnNulls(true);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }
    
    @Bean
    public PlatformTransactionManager busTransactionManager(@Qualifier("busDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public TransactionTemplate busTransactionTemplate(@Qualifier("busTransactionManager") PlatformTransactionManager transactionManager) {
        return new TransactionTemplate(transactionManager);
    }
}

事務使用規范

單數據源事務

通過@Transactional(transactionManager = "xxxTransactionManager")指定事務管理器

跨數據源事務

方式一:編程式事務
public void createOrderWithMonitorLog(OrderDTO orderDTO) {
    // 1. 定義事務屬性(默認:隔離級別DEFAULT,傳播行為REQUIRED)
    DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
    // 2. 開啟兩個數據源的事務,獲取事務狀態(用于后續提交/回滾)
    TransactionStatus busTxStatus = busTransactionManager.getTransaction(txDefinition);
    TransactionStatus manTxStatus = manTransactionManager.getTransaction(txDefinition);

    try {
        // 3. 執行業務庫:插入訂單
        orderMapper.insertOrder(orderDTO); 
        // 4. 執行管理庫:記錄訂單創建的監控日志
        MonitorLog log = new MonitorLog()
                .setBizType("ORDER_CREATE")
                .setBizId(orderDTO.getOrderId())
                .setOperateTime(System.currentTimeMillis());
        monitorLogMapper.insertMonitorLog(log);

        // 5. 無異常時,提交兩個數據源的事務(順序可調整,建議先提交非核心庫)
        busTransactionManager.commit(busTxStatus);
        manTransactionManager.commit(manTxStatus);
        System.out.println("跨數據源事務執行成功,訂單創建+日志記錄完成");
    } catch (Exception e) {
        // 6. 有異常時,回滾所有事務
        if (!busTxStatus.isRollbackOnly()) {
            busTransactionManager.rollback(busTxStatus);
        }
        if (!manTxStatus.isRollbackOnly()) {
            manTransactionManager.rollback(manTxStatus);
        }
        // 7. 記錄異常日志,必要時觸發補償機制(如訂單回滾后刪除已生成的日志)
        System.err.println("跨數據源事務執行失敗,已回滾:" + e.getMessage());
        throw new BusinessException("訂單創建失敗,請重試", e);
    }
}
方式二:分布式事務
@Service
public class OrderService {
    // 其他注入代碼...

    // 全局事務注解:rollbackFor指定異常回滾,timeout設置超時時間
    @GlobalTransactional(rollbackFor = Exception.class, timeout = 60000)
    public void createOrderWithMonitorLog(OrderDTO orderDTO) {
        // 1. 操作MySQL:插入訂單(Seata自動記錄undo日志)
        orderMapper.insertOrder(orderDTO);
        // 2. 操作TDengine:記錄監控日志(Seata自動記錄undo日志)
        MonitorLog log = new MonitorLog()
                .setBizType("ORDER_CREATE")
                .setBizId(orderDTO.getOrderId())
                .setOperateTime(System.currentTimeMillis());
        monitorLogMapper.insertMonitorLog(log);
        
        // 若此處拋出異常,Seata會協調兩個數據源自動回滾;無異常則自動提交
    }
}


責任編輯:武曉燕 來源: 一安未來
相關推薦

2024-10-30 10:22:17

2023-09-07 08:39:39

copy屬性數據源

2020-03-13 14:05:14

SpringBoot+數據源Java

2025-11-26 01:25:00

數據源系統分庫分表

2023-06-07 08:08:37

MybatisSpringBoot

2020-06-02 07:55:31

SpringBoot多數據源

2023-01-04 09:33:31

SpringBootMybatis

2022-05-10 10:43:35

數據源動態切換Spring

2020-12-31 07:55:33

spring bootMybatis數據庫

2020-11-24 09:56:12

數據源讀寫分離

2025-04-14 01:00:00

Calcite電商系統MySQL

2010-12-27 09:59:11

ODBC數據源

2009-06-15 13:24:46

JBoss數據源

2023-10-31 07:52:53

多數據源管理后端

2009-08-14 10:26:27

ibatis多數據源

2022-05-18 12:04:19

Mybatis數據源Spring

2024-04-30 09:17:06

SpringBootMybatis動態數據源

2017-09-04 14:52:51

Tomcat線程數據源

2023-02-06 14:44:00

嚴選數據源DB

2023-11-27 09:16:53

Python數據源類型
點贊
收藏

51CTO技術棧公眾號

桃子视频成人app| 国产自产在线视频| 一级特黄妇女高潮| xxxx成人| 成人午夜视频在线| 日本在线成人一区二区| 免费日本视频一区| 欧美在线三区| 亚洲日本中文字幕区| 好吊妞www.84com只有这里才有精品| 日本中文字幕在线一区| 欧美高清视频免费观看| 亚洲精品一区二区三区在线| 欧美不卡视频一区发布| 亚洲影视资源| 欧美精品国产精品日韩精品| 亚洲精品高潮| 日本高清视频一区| 偷偷www综合久久久久久久| 国内精品400部情侣激情| av午夜在线| 视频三区在线| 色天天综合网| 欧美一区二区高清| 99热播精品免费| 欧美日韩国产影片| 完全免费av在线播放| 国产日韩精品一区二区三区在线| 特级黄色录像片| 久久久久免费| 久久av一区二区三区亚洲| 欧美三级网页| 高清视频一区| 综合激情视频| 国产精品亚洲一区二区三区| 亚洲黄页网站| 日本精品久久中文字幕佐佐木| 中文久久电影小说| 大量国产精品视频| 激情综合婷婷| 久久精品99久久久久久久久| 日韩av一级片| 日韩av在线免费播放| 91视频免费版污| 国产资源精品在线观看| 亚洲精品中文在线影院| 久久久久久久久久久久久久 | 91午夜在线| 亚洲国产成人精品电影| 亚洲成人精品| 丁香婷婷激情| 69av视频在线播放| 久久久天堂av| 亚洲1区在线| 波多野结衣家庭教师视频| 亚洲精品国产精品久久清纯直播 | 欧美高清视频一二三区| 欧美日本精品一区二区三区| 国模精品娜娜一二三区| 欧美3p在线观看| 欧美富婆性猛交| 一区二区三区在线电影| heyzo在线观看| 国产做受高潮69| 一区在线中文字幕| 丁香激情综合国产| 东凛在线观看| 欧美午夜女人视频在线| av今日在线| 色吧亚洲视频| 日韩一区二区免费视频| 天堂资源在线中文精品| 51漫画成人app入口| 亚洲 欧美 日韩 国产综合 在线| 欧美大荫蒂xxx| 欧美日韩在线视频首页| 一区二区三区成人精品| 经典三级一区二区| www.日本视频| 久久久久久九九九九| 国产一区二区三区18| 国产亚洲欧美日韩日本| 污视频网站在线看| 国产精品嫩模av在线| 成人久久18免费网站麻豆| 亚洲aaa激情| 欧美日韩在线三区| 麻豆免费在线视频| 日韩乱码在线视频| 99re这里只有精品首页| 欧美少妇性xxxx| 你懂得影院夜精品a| 国产精品久久久久白浆| 亚洲制服欧美久久| 国产欧美精品一区二区| 一区二区三区黄色| 555www色欧美视频| 悠悠色在线精品| 久久亚洲精品小早川怜子| 欧美日韩一区自拍| 久本草在线中文字幕亚洲| 丝袜美腿一区| yellow视频在线观看一区二区| 综合国产精品久久久| 亚洲人和日本人hd| 欧美男同性恋视频网站| 99thz桃花论族在线播放| 亚洲在线观看视频网站| 宅男在线国产精品| 久久午夜电影网| 亚洲一区欧美二区| 欧美 日韩 国产一区二区在线视频 | av网站在线看| 国产在线三区| 欧美一区二区视频| 国产在线观看福利| 一区二区在线不卡| 亚洲国产一区二区精品视频 | 日韩欧美极品在线观看| 91久久精品美女| 久久av在线播放| 日韩黄色片在线观看| 中文字幕一区二区三区免费视频| 亚洲精品欧美日韩专区| 欧日韩在线观看| 国产精品黄视频| 99国产超薄肉色丝袜交足的后果| 国产精品久久97| caoporen国产精品| 久久精品国产综合精品| 神马影院午夜我不卡影院| 亚洲国产午夜伦理片大全在线观看网站 | 免费在线观看视频a| 国产福利视频在线播放| 欧美精品一级二级| 91亚洲人成网污www| 日韩三区在线| 黄视频网站在线看| 亚洲第一成年免费网站| 人成免费电影一二三区在线观看| 岛国在线视频| 欧美美女被草| 99精品国产一区二区三区| 日韩高清不卡一区二区三区| 久久你懂得1024| 91麻豆精品国产91久久久久 | 最新av在线网站| caopen在线视频| 91成人入口| 老司机精品视频在线| 亚洲精品伦理在线| 日日摸夜夜添夜夜添精品视频| 日本精品一区二区| 成人综合婷婷国产精品久久 | 国产精品调教视频| 欧美黑人粗大| 大色综合视频网站在线播放| 狠狠色丁香九九婷婷综合五月| 亚洲综合图片区| 中日韩美女免费视频网址在线观看| 91精品国产综合久久久久久丝袜| 蜜桃免费在线视频| 国产一区二区三区朝在线观看| 黄色成人在线网站| 亚洲无人区一区| 91精品国产91久久| 91精品国产毛片武则天| 69av亚洲| 国内精品久久久久久久影视蜜臀| 中文字幕中文在线不卡住| 欧美性猛交xxx| 丝袜在线视频| 国产日产久久高清欧美一区| 欧美系列电影免费观看| 手机看片福利在线观看| 日韩精品一区二区三区电影| 97精品久久久中文字幕免费| 欧美精品videofree1080p| 国产精品视频自在线| 色姑娘综合av| 黑人与亚洲人色ⅹvideos| 岛国精品一区| 国产精品视频在线看| 欧美日韩不卡合集视频| 国产一级特黄a大片免费| 女同另类激情重口| 香蕉加勒比综合久久| 国内成+人亚洲| 污污影院在线观看| 成人免费福利片| 日本伊人精品一区二区三区介绍 | 青草综合视频| av免费在线一区二区三区| 欧美日韩小视频| 国产精品美女午夜爽爽| 美女999久久久精品视频| 亚洲人成小说网站色在线| 久久久综合九色合综国产精品| 亚洲精品在线观看视频| 日韩一级性生活片|