最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路

 更新時間:2021年01月20日 09:10:43   作者:左羽  
這篇文章主要介紹了MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

關(guān)于多數(shù)據(jù)源解決方案

目前在SpringBoot框架基礎(chǔ)上多數(shù)據(jù)源的解決方案大多手動創(chuàng)建多個DataSource,后續(xù)方案有三:

  1. 繼承org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,使用AOP切面注入相應(yīng)的數(shù)據(jù)源 ,但是這種做法僅僅適用單Service方法使用一個數(shù)據(jù)源可行,如果單Service方法有多個數(shù)據(jù)源執(zhí)行會造成誤讀。
  2. 通過DataSource配置 JdbcTemplateBean,直接使用 JdbcTemplate操控數(shù)據(jù)源。
  3. 分別通過DataSource創(chuàng)建SqlSessionFactory并掃描相應(yīng)的Mapper文件和Mapper接口。

MybatisPlus的多數(shù)據(jù)源

我通過閱讀源碼,發(fā)現(xiàn)MybatisPlus的多數(shù)據(jù)源解決方案正是AOP,繼承了org.springframework.jdbc.datasource.AbstractDataSource,有自己對ThreadLocal的處理。通過注解切換數(shù)據(jù)源。也就是說,MybatisPlus只支持在單Service方法內(nèi)操作一個數(shù)據(jù)源,畢竟官網(wǎng)都指明——“強烈建議只注解在service實現(xiàn)上”。

而后,注意看com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder,也就是MybatisPlus是如何切換數(shù)據(jù)源的。

重點看:

/**
 * 為什么要用鏈表存儲(準(zhǔn)確的是棧)
 * <pre>
 * 為了支持嵌套切換,如ABC三個service都是不同的數(shù)據(jù)源
 * 其中A的某個業(yè)務(wù)要調(diào)B的方法,B的方法需要調(diào)用C的方法。一級一級調(diào)用切換,形成了鏈。
 * 傳統(tǒng)的只設(shè)置當(dāng)前線程的方式不能滿足此業(yè)務(wù)需求,必須模擬棧,后進先出。
 * </pre>
 */
 private static final ThreadLocal<Deque<String>> LOOKUP_KEY_HOLDER = new ThreadLocal() {
 @Override
 protected Object initialValue() {
  return new ArrayDeque();
 }
 };

這段話翻譯為大家都能懂得的意思就是“可以同時操控多個數(shù)據(jù)源”。那么,在MYSQL中,有語法為schemaName+. +tableName,如此一來就不會誤走數(shù)據(jù)源了。

我繼續(xù)看MybatisPlus是如何利用mybatis本身的ORM機制將實體類自動映射以及生成SQL語句的(這里插一句,MybatisPlus的源碼易讀懂,寫的很不錯)。無意看到了注解com.baomidou.mybatisplus.annotation.TableName中的schema,如果在類上加schema,在生成SQL語句時就會生成schemaName+. +tableName格式。

MybatisPlus多數(shù)據(jù)源事務(wù)(JTA

簡單說明一下JTA

JTA包括事務(wù)管理器(Transaction Manager)和一個或多個支持 XA 協(xié)議的資源管理器 ( Resource Manager ) 兩部分, 可以將資源管理器看做任意類型的持久化數(shù)據(jù)存儲;事務(wù)管理器則承擔(dān)著所有事務(wù)參與單元的協(xié)調(diào)與控制。

JTA只是提供了一個接口,并沒有提供具體的實現(xiàn)。

不過Atomikos對其進行了實現(xiàn),而后SpringBoot將其進行了整合,對其進行了托管,很方便開發(fā)者拿來即用。

其中事務(wù)管理器的主要部分為UserTransaction 接口,開發(fā)人員通過此接口在信息系統(tǒng)中實現(xiàn)分布式事務(wù);而資源管理器則用來規(guī)范提供商(如數(shù)據(jù)庫連接提供商)所提供的事務(wù)服務(wù),它約定了事務(wù)的資源管理功能,使得 JTA 可以在異構(gòu)事務(wù)資源之間執(zhí)行協(xié)同溝通。

通常接入JTA步驟(目的就是讓JTAUserTransaction接管驅(qū)動為分布式的數(shù)據(jù)源,通常為AtomikosDataSourceBean):

  • 配置好AtomikosDataSourceBean。
  • AtomikosDataSourceBean交給SqlSessionFactory
  • 配置UserTransaction事務(wù)管理。

但是我們用的是MybatisPlus,我們需要做的是接管MybatisPlus每一個數(shù)據(jù)源的配置,然后再把數(shù)據(jù)源依次交給MybatisPlus進行管理。

看看MybatisPlus是怎么進行多數(shù)據(jù)源配置的,源碼里有這幾個地方需要重點看一下:

  • com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider,這個就是MybatisPlus多數(shù)據(jù)源配置的方式,利用HashMap來裝載。
  • com.baomidou.dynamic.datasource.DynamicDataSourceCreator,這個是每個數(shù)據(jù)源的配置方式。

其中com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider實現(xiàn)了接口com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider,是該接口的默認(rèn)的實現(xiàn)。也就是說我們只需要實現(xiàn)該接口,自己配置多數(shù)據(jù)源以及每個數(shù)據(jù)源的驅(qū)動,成為該接口的默認(rèn)實現(xiàn)就OK。

實現(xiàn)該接口,配置多數(shù)據(jù)源:

package xxx.xxx.xxx.config;

import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : zuoyu
 * @description : 接管MybatisPlus多數(shù)據(jù)源至Atomikos管理
 * @date : 2020-06-01 16:36
 **/
@Service
@Primary
public class DynamicDataSourceProviderImpl implements DynamicDataSourceProvider {


 /**
  * 配置文件數(shù)據(jù)的松散綁定
  */
 private final DynamicDataSourceProperties properties;

 /**
  * Atomikos驅(qū)動數(shù)據(jù)源創(chuàng)建
  */
 private final AtomikosDataSourceCreator atomikosDataSourceCreator;

 public DynamicDataSourceProviderImpl(DynamicDataSourceProperties properties, AtomikosDataSourceCreator atomikosDataSourceCreator) {
  this.properties = properties;
  this.atomikosDataSourceCreator = atomikosDataSourceCreator;
 }

 @Override
 public Map<String, DataSource> loadDataSources() {
  Map<String, DataSourceProperty> dataSourcePropertiesMap = properties.getDatasource();
  Map<String, DataSource> dataSourceMap = new HashMap<>(dataSourcePropertiesMap.size() * 2);
  for (Map.Entry<String, DataSourceProperty> item : dataSourcePropertiesMap.entrySet()) {
   String pollName = item.getKey();
   DataSourceProperty dataSourceProperty = item.getValue();
   dataSourceProperty.setPollName(pollName);
   dataSourceMap.put(pollName, atomikosDataSourceCreator.createDataSource(dataSourceProperty));
  }
  return dataSourceMap;
 }
}

Atomikos驅(qū)動數(shù)據(jù)源創(chuàng)建:

package xxx.xxx.xxx.config;

import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;

/**
 * @author : zuoyu
 * @description : 事務(wù)數(shù)據(jù)源
 * @date : 2020-06-01 17:30
 **/
@Component
public class AtomikosDataSourceCreator {
 /**
  * 創(chuàng)建數(shù)據(jù)源
  *
  * @param dataSourceProperty 數(shù)據(jù)源信息
  * @return 數(shù)據(jù)源
  */
 public DataSource createDataSource(DataSourceProperty dataSourceProperty) {
  MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
  mysqlXaDataSource.setUrl(dataSourceProperty.getUrl());
  mysqlXaDataSource.setPassword(dataSourceProperty.getPassword());
  mysqlXaDataSource.setUser(dataSourceProperty.getUsername());
  AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
  xaDataSource.setXaDataSource(mysqlXaDataSource);
  xaDataSource.setMinPoolSize(5);
  xaDataSource.setBorrowConnectionTimeout(60);
  xaDataSource.setMaxPoolSize(20);
  xaDataSource.setXaDataSourceClassName(dataSourceProperty.getDriverClassName());
  xaDataSource.setTestQuery("SELECT 1 FROM DUAL");
  xaDataSource.setUniqueResourceName(dataSourceProperty.getPollName());
  return xaDataSource;
 }
}

配置JTA事務(wù)管理器:

package xxx.xxx.xxx.config;

import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;

import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

/**
 * @author : zuoyu
 * @description : 分布式事務(wù)配置
 * @date : 2020-06-01 17:55
 **/
@Configuration
@EnableTransactionManagement
public class TransactionManagerConfig {

 @Bean(name = "userTransaction")
 public UserTransaction userTransaction() throws Throwable {
  UserTransactionImp userTransactionImp = new UserTransactionImp();
  userTransactionImp.setTransactionTimeout(10000);
  return userTransactionImp;
 }

 @Bean(name = "atomikosTransactionManager")
 public TransactionManager atomikosTransactionManager() throws Throwable {
  UserTransactionManager userTransactionManager = new UserTransactionManager();
  userTransactionManager.setForceShutdown(false);
  return userTransactionManager;
 }

 @Bean(name = "transactionManager")
 @DependsOn({"userTransaction", "atomikosTransactionManager"})
 public PlatformTransactionManager transactionManager() throws Throwable {
  return new JtaTransactionManager(userTransaction(), atomikosTransactionManager());
 }
}

如此,即可

這樣一來便可解決MybatisPlus多數(shù)據(jù)源的誤走,且支持多數(shù)據(jù)源下的事務(wù)問題。

做任何事情,重要的是思路,而不是搬磚。

到此這篇關(guān)于MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路的文章就介紹到這了,更多相關(guān)MybatisPlus多數(shù)據(jù)源事務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java?Spring的啟動原理詳解

    java?Spring的啟動原理詳解

    大家好,本篇文章主要講的是java?Spring的啟動原理詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • 淺析JAVA常用JDBC連接數(shù)據(jù)庫的方法總結(jié)

    淺析JAVA常用JDBC連接數(shù)據(jù)庫的方法總結(jié)

    本篇文章是對在JAVA中常用JDBC連接數(shù)據(jù)庫的方法進行了詳細(xì)的總結(jié)分析,需要的朋友參考下
    2013-07-07
  • MybatisPlus中QueryWrapper常用方法總結(jié)

    MybatisPlus中QueryWrapper常用方法總結(jié)

    MyBatis-Plus是一個Mybatis增強版工具,在MyBatis上擴充了其他功能沒有改變其基本功能,為了簡化開發(fā)提交效率而存在,queryWrapper是mybatis plus中實現(xiàn)查詢的對象封裝操作類,本文就給大家總結(jié)了MybatisPlus中QueryWrapper的常用方法,需要的朋友可以參考下
    2023-07-07
  • Spring Boot+Drools規(guī)則引擎整合詳解

    Spring Boot+Drools規(guī)則引擎整合詳解

    本篇文章主要介紹了Spring Boot+Drools規(guī)則引擎整合,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • IDEA中Java出現(xiàn)無效的源發(fā)行版錯誤的解決辦法

    IDEA中Java出現(xiàn)無效的源發(fā)行版錯誤的解決辦法

    這篇文章主要給大家介紹了關(guān)于IDEA中Java出現(xiàn)無效的源發(fā)行版錯誤的解決辦法,IDEA中Java出現(xiàn)?效的源發(fā)?版解決辦法出現(xiàn)該問題的原因是項?Project當(dāng)中的jdk與電腦當(dāng)中的jdk版本不?致造成的,需要的朋友可以參考下
    2023-10-10
  • @Autowired注解在抽象類中失效的原因及解決

    @Autowired注解在抽象類中失效的原因及解決

    這篇文章主要介紹了@Autowired注解在抽象類中失效的原因及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 小白教程! Linux服務(wù)器上JDK安裝配置方法

    小白教程! Linux服務(wù)器上JDK安裝配置方法

    這篇文章主要為大家詳細(xì)介紹了Linux服務(wù)器上JDK安裝配置方法,小白教程!具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • MyBatis的collection和association的使用解讀

    MyBatis的collection和association的使用解讀

    這篇文章主要介紹了MyBatis的collection和association的使用解讀
    2023-12-12
  • Mybatis注解實現(xiàn)多數(shù)據(jù)源讀寫分離詳解

    Mybatis注解實現(xiàn)多數(shù)據(jù)源讀寫分離詳解

    這篇文章主要給大家介紹了關(guān)于Mybatis注解實現(xiàn)多數(shù)據(jù)源讀寫分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • JAVA面向?qū)ο笤O(shè)計寵物類方式

    JAVA面向?qū)ο笤O(shè)計寵物類方式

    本指南涉及JAVA面向?qū)ο蟮膶櫸镱愒O(shè)計,包括寵物類的父類及其子類小貓類和小狗類,用戶可以選擇養(yǎng)貓或養(yǎng)狗,給寵物起名字,實現(xiàn)喂食互動,同時寵物具有飽食度和快樂度屬性,適合初學(xué)者學(xué)習(xí)面向?qū)ο笤O(shè)計
    2024-10-10

最新評論

梁河县| 观塘区| 芜湖市| 郎溪县| 孟津县| 隆子县| 鲁山县| 满城县| 惠州市| 永兴县| 治多县| 舟山市| 沙田区| 凤阳县| 黄石市| 五原县| 新兴县| 仁布县| 屯门区| 长白| 兖州市| 扎兰屯市| 延川县| 张北县| 芦溪县| 阿合奇县| 仁化县| 沙雅县| 南安市| 广丰县| 墨脱县| 双江| 呼图壁县| 景谷| 牟定县| 北海市| 台中市| 吉木萨尔县| 南丹县| 肇庆市| 松溪县|