欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

  1. 繼承org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,使用AOP切面注入相應(yīng)的數(shù)據(jù)源 ,但是這種做法僅僅適用單Service方法使用一個(gè)數(shù)據(jù)源可行,如果單Service方法有多個(gè)數(shù)據(jù)源執(zhí)行會(huì)造成誤讀。
  2. 通過DataSource配置 JdbcTemplateBean,直接使用 JdbcTemplate操控?cái)?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,有自己對(duì)ThreadLocal的處理。通過注解切換數(shù)據(jù)源。也就是說,MybatisPlus只支持在單Service方法內(nèi)操作一個(gè)數(shù)據(jù)源,畢竟官網(wǎng)都指明——“強(qiáng)烈建議只注解在service實(shí)現(xiàn)上”。

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

重點(diǎn)看:

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

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

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

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

簡單說明一下JTA

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

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

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

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

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

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

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

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

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

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

實(shí)現(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ū)動(dòng)數(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ū)動(dòng)數(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java圖片色階調(diào)整和亮度調(diào)整代碼示例

    java圖片色階調(diào)整和亮度調(diào)整代碼示例

    這篇文章主要介紹了java圖片色階調(diào)整和亮度調(diào)整代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • java筆記學(xué)習(xí)之操作符

    java筆記學(xué)習(xí)之操作符

    本篇文章給大家分享了關(guān)于Java中操作符的相關(guān)知識(shí)點(diǎn)以及難點(diǎn)總結(jié),有需要的朋友參考學(xué)習(xí)下吧。
    2018-04-04
  • Spring MVC---數(shù)據(jù)綁定和表單標(biāo)簽詳解

    Spring MVC---數(shù)據(jù)綁定和表單標(biāo)簽詳解

    本篇文章主要介紹了Spring MVC---數(shù)據(jù)綁定和表單標(biāo)簽詳解,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-01-01
  • java Clone接口和深拷貝詳解

    java Clone接口和深拷貝詳解

    今天小編就為大家分享一篇關(guān)于Java Clonable接口和深拷貝詳解上的深入了解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2021-08-08
  • SpringBoot RESTful風(fēng)格入門講解

    SpringBoot RESTful風(fēng)格入門講解

    RESTful是一種web軟件風(fēng)格,它不是標(biāo)準(zhǔn)也不是協(xié)議,它不一定要采用,只是一種風(fēng)格,它倡導(dǎo)的是一個(gè)資源定位(url)及資源操作的風(fēng)格,這篇文章主要介紹了SpringBoot使用RESTful接口
    2022-11-11
  • Spring AOP定義Before增加實(shí)戰(zhàn)案例詳解

    Spring AOP定義Before增加實(shí)戰(zhàn)案例詳解

    這篇文章主要介紹了Spring AOP定義Before增加,結(jié)合實(shí)例形式詳細(xì)分析了Spring面向切面AOP定義Before增加相關(guān)定義與使用技巧,需要的朋友可以參考下
    2020-01-01
  • java中g(shù)radle項(xiàng)目報(bào)錯(cuò)org.gradle?.api.plugins.MavenPlugin解決辦法

    java中g(shù)radle項(xiàng)目報(bào)錯(cuò)org.gradle?.api.plugins.MavenPlugin解決辦法

    在使用Gradle時(shí)開發(fā)者可能會(huì)遇到org.gradle?.api.plugins.MavenPlugin報(bào)錯(cuò)提醒,這篇文章主要給大家介紹了關(guān)于java中g(shù)radle項(xiàng)目報(bào)錯(cuò)org.gradle?.api.plugins.MavenPlugin的解決辦法,需要的朋友可以參考下
    2023-12-12
  • Myeclipse工程發(fā)布時(shí)端口占用問題的解決方法

    Myeclipse工程發(fā)布時(shí)端口占用問題的解決方法

    這篇文章主要介紹了Myeclipse工程發(fā)布時(shí)端口占用問題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 在Spring中編寫事務(wù)的介紹

    在Spring中編寫事務(wù)的介紹

    今天小編就為大家分享一篇關(guān)于在Spring中編寫事務(wù)的介紹,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java使用反射調(diào)用方法示例

    Java使用反射調(diào)用方法示例

    這篇文章主要介紹了Java使用反射調(diào)用方法,結(jié)合實(shí)例形式分析了java使用反射調(diào)用對(duì)象方法的相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07

最新評(píng)論