原 spring boot Druid多

SpringBoot 多数据源配置

spring 多数据源配置一般有两种方案:

1、在spring项目启动的时候直接配置两个不同的数据源,不同的sessionFactory。在dao 层根据不同业务自行选择使用哪个数据源的session来操作。

2、配置多个不同的数据源,使用一个sessionFactory,在业务逻辑使用的时候自动切换到不同的数据源,有一个种是在拦截器里面根据不同的业务现切换到不同的datasource;有的会在业务层根据业务来自动切换。但这种方案在多线程并发的时候会出现一些问题,需要使用threadlocal等技术来实现多线程竞争切换数据源的问题。

【我就只讨论第一种方案】

spring多事务配置主要体现在db配置这块,配置不同的数据源和不同的session

1、pom.xml核心包:

<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
<!-- 阿里 连接池 -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>${druid.version}</version>
</dependency>
<!--分布式事务支持 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>

2、application.yml属性配置:

spring:
  datasource:
    one:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.1.206:3306/testOne?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false
      username: root
      password: 1234
    two:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.1.206:3306/testTwo?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false
      username: root
      password: 1234

3、接收数据源①:dataSource的Properties

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;

@Data
@Component
@ConfigurationProperties(prefix = "spring.datasource.one")
public class OneDataSourceProperties {

    private String driverClassName;

    private String url;

    private String username;

    private String password;
}

4、设置①:dataSource

@Configuration
@MapperScan(basePackages = "com.xin.dream.one.dao", sqlSessionTemplateRef = "oneSqlSessionTemplate")
public class OneDatabaseConfig {
	@Autowired
	public OneDataSourceProperties oneDataSourceProperties;
	@Primary
	@Bean(name = "oneDataSource", destroyMethod = "close")
	public DataSource oneDataSource() {
		DruidXADataSource datasource = new DruidXADataSource();
    	BeanUtils.copyProperties(oneDataSourceProperties,datasource);
    	AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(datasource);
        xaDataSource.setUniqueResourceName("oneDataSource");
        return xaDataSource;
	}

	@Primary
	@Bean(name = "oneSqlSessionFactory")
	public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDataSource") DataSource oneDataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(oneDataSource);
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		bean.setMapperLocations(resolver.getResources("classpath:com/xin/dream/one/mapper/*.xml"));
		return bean.getObject();
	}

	@Primary
	@Bean(name = "oneSqlSessionTemplate")
	public SqlSessionTemplate oneSqlSessionTemplate(
			@Qualifier("oneSqlSessionFactory") SqlSessionFactory oneSqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(oneSqlSessionFactory);
	}
}

5、第②数据源和①的步骤一样,改掉别名,和去掉@Primary,就好了。这个时候事务已经是被管理的了

源码地址:https://gitee.com/bianxin.com/SpringBootAtomikos

在开发中遇见问题

配置文件:

spring:
  jta:
    atomikos:
      datasource:
        oneData:
          max-pool-size: 25
          min-pool-size: 3
          max-lifetime: 20000
          xa-data-source-class-name: com.alibaba.druid.pool.xa.DruidXADataSource
          borrow-connection-timeout: 10000
          unique-resource-name: fs
          xa-properties:
            password: 1234
            username: root
            url: jdbc:mysql://192.168.1.206:3306/testOne?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false
        twoData:
          max-pool-size: 25
          min-pool-size: 3
          max-lifetime: 20000
          xa-data-source-class-name: com.alibaba.druid.pool.xa.DruidXADataSource
          unique-resource-name: party
          borrow-connection-timeout: 10000 
          xa-properties:
            password: 1234
            username: root
            url: jdbc:mysql://192.168.1.206:3306/testOne?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false
    enabled: true

为了节减代码量dataSource配置文件为:

@Configuration
@MapperScan(basePackages = "com.xin.dream.one.dao", sqlSessionTemplateRef = "oneSqlSessionTemplate")
public class OneDatabaseConfig {
	
	@Primary
	@Bean(name = "oneDataSource", destroyMethod = "close")
	@ConfigurationProperties(prefix = "spring.jta.atomikos.datasource.oneData")
	public DataSource oneDataSource() {
		return new AtomikosDataSourceBean();
	}

	@Primary
	@Bean(name = "oneSqlSessionFactory")
	public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDataSource") DataSource oneDataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(oneDataSource);
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		bean.setMapperLocations(resolver.getResources("classpath:com/xin/dream/one/mapper/*.xml"));
		return bean.getObject();
	}

	@Primary
	@Bean(name = "oneSqlSessionTemplate")
	public SqlSessionTemplate oneSqlSessionTemplate(
			@Qualifier("oneSqlSessionFactory") SqlSessionFactory oneSqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(oneSqlSessionFactory);
	}

}

当有多个数据源的时候报错:

Caused by: com.atomikos.jdbc.AtomikosSQLException: Cannot initialize AtomikosDataSourceBean
	at com.atomikos.jdbc.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:46) ~[transactions-jdbc-3.9.3.jar:na]
	at com.atomikos.jdbc.AbstractDataSourceBean.init(AbstractDataSourceBean.java:306) ~[transactions-jdbc-3.9.3.jar:na]
	at org.springframework.boot.jta.atomikos.AtomikosDataSourceBean.afterPropertiesSet(AtomikosDataSourceBean.java:49) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
	... 80 common frames omitted
Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_131]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_131]
	at com.atomikos.beans.PropertyUtils.setDirectProperty(PropertyUtils.java:205) ~[atomikos-util-3.9.3.jar:na]
	at com.atomikos.beans.PropertyUtils.setProperty(PropertyUtils.java:110) ~[atomikos-util-3.9.3.jar:na]
	at com.atomikos.beans.PropertyUtils.setProperties(PropertyUtils.java:186) ~[atomikos-util-3.9.3.jar:na]
	at com.atomikos.jdbc.AtomikosDataSourceBean.doInit(AtomikosDataSourceBean.java:196) ~[transactions-jdbc-3.9.3.jar:na]
	at com.atomikos.jdbc.AbstractDataSourceBean.init(AbstractDataSourceBean.java:296) ~[transactions-jdbc-3.9.3.jar:na]
	... 83 common frames omitted

我跟踪了源码,水平有限,暂时还没弄懂原因,想直接new AtomikosDataSourceBean()或者简单的赋值,怎么弄?望朋友们指点下?

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

《Springboot极简教程》 第11章 Springboot集成mongodb开发小结

本章我们通过SpringBoot集成mongodb,Java,Kotlin开发一个极简社区文章博客系统。

704
来自专栏龙渊阁测试精英

Jmeter(二十)_Mock接口

Mock通常是指,在测试一个对象时,我们构造一些假的对象来模拟与其交互。而这些Mock对象的行为是我们事先设定且符合预期。通过这些Mock对象来测试对象在正常逻...

872
来自专栏Spring相关

Getway网关管理ZUUL

微服务架构体系中,通常一个业务系统会有很多的微服务,比如:OrderService、ProductService、UserService...,为了让调用更简单...

964
来自专栏互联网杂技

SpringBoot ( 十一 ) :SpringBoot 中 mongodb 的使用

mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多。由于很多公司使用了云服务,服务器默认都开放了外网地址,...

982
来自专栏程序之美

第五节 微服务OTRS 补充客户端负载均衡

spring could在客户端负载均衡有两种选择一种是ribbon+restTemplate,另一种是feign。本主要讲解下基于ribbon+rest。当然...

531
来自专栏ImportSource

Spring Boot下的TDD(测试驱动开发)

首先来看下TDD三原则吧: You are not allowed to write any production code unless it is to m...

74611
来自专栏battcn

一起来学Spring Cloud(F版) | 第三篇:注解式HTTP请求Feign

注解式的 Feign 使得 Java HTTP 客户端编写更方便。Feign 灵感来源于安卓网络编程框架 Retrofit、JAXRS-2.0 和 WebSoc...

582
来自专栏圣杰的专栏

ABP入门系列(11)——编写单元测试

源码路径:Github-LearningMpaAbp 1. 前言 In computer programming, unit testing is a soft...

2308
来自专栏owent

atapp的c binding和c#适配

这两天在做服务器框架的C的接口导出和C#的接入。之所以要做这么个东西是因为之前的服务器框架(atsf4g-co)已经完成了通信层面和基本设计模式的细节部分,而且...

581
来自专栏菩提树下的杨过

mybatis: 利用多数据源实现分库存储

之前写过一篇mybatis 使用经验小结 提到过多数据源的处理方式,虽然简单但是姿势不太优雅,今天介绍一些更美观的办法: spring中有一个AbstractR...

2055

扫码关注云+社区