springbootspring 整合使用技术分享

SpringBoot2.x实现链式事务(分库事务)

2020-11-30  本文已影响0人  小胖学编程

在实际项目中,可能需要配置多个数据库,某一段代码需要操作多个数据库时,如何保持事务一致性?

需要说明的是,多数据库的数据一致性不是分布式事务。Spring也提供了ChainedTransactionManager类来管理我们多数据源。

1. 实现多数据源的配置

durid数据源为例子:

配置信息可以参考:SpringBoot2.x实现动态切换数据源(实现读写分离)

@Slf4j
@Configuration
//指定需要扫描的Dao文件
@MapperScan(basePackages="com.xxx.mapper",sqlSessionTemplateRef = "xxxSqlSessionTemplate")
public class XxxDataSourceConfig {
    //加载项目中resources中的XxxDao.xml文件
    @Value("${xxxsql.mapperLocations}")
    private String mapperLocations;

    //加载Mybatisde1全局的配置文件
    @Value("${mysql.configLocation}")
    private String configLocation;

    /**
     * 数据源配置
     */
    @Bean(name = "xxxDataSource")
    //读取配置文件的配置信息到DruidDataSource对象中
    @ConfigurationProperties(prefix = "xxxsql.datasource")
    public DataSource writeDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }

    @Bean(name="xxxSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactorys(@Qualifier("xxxDataSource") DataSource dataSource) throws Exception {
        try {
            SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
             //获取配置文件的dataSource对象
            sessionFactoryBean.setDataSource(dataSource);
            //设置mybatis-config.xml配置文件位置
            sessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
            //设置mapper.xml文件所在位置
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources(mapperLocations);
            sessionFactoryBean.setMapperLocations(resources);
            return sessionFactoryBean.getObject();
        } catch (IOException e) {
            log.error("mybatis解析 mapper*xml 失败",e);
            return null;
        } catch (Exception e) {
            log.error("mybatis sqlSessionFactoryBean创建失败",e);
            return null;
        }
    }

    @Bean(name = "xxxSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("xxxSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    //事务管理
    @Bean(name = "xxxTransactionManager")
    public PlatformTransactionManager xxxTransactionManager(@Qualifier("xxxDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

配置mybatis的全局配置:目录:resources/mybatis/mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true" />
        <setting name="lazyLoadingEnabled" value="true" />
        <setting name="multipleResultSetsEnabled" value="true" />
        <setting name="useColumnLabel" value="true" />
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="useGeneratedKeys" value="true" />
        <setting name="defaultExecutorType" value="SIMPLE" />
        <setting name="defaultStatementTimeout" value="25000" />
    </settings>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
    </typeAliases>
    
</configuration>

yml的配置文件:

xxxsql:
  mapperLocations: classpath*:mybatis/xxx/**/*.xml
  configLocation: classpath:/mybatis/mybatis-config.xml
  doubleWriting: false
  datasource:
    url: jdbc:mysql://ip地址:端口/数据库名?useSSL=false
    username: 
    password: 
    driver-class-name: com.mysql.jdbc.Driver
    minIdle: 5
    maxActive: 100
    initialSize: 10
    maxWait: 60000

2. 实现链式事务的配置

实现链式事务,是把两个事务管理器都交由ChainedTransactionManager来统一管理。若A数据源提交,但是B数据源出现异常,那么A,B数据源均要回滚。

引入依赖:

<!-- Spring Data Commons -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-commons</artifactId>
    <version>2.0.9.RELEASE</version>
</dependency>

注:platformTransactionManager事务管理器声明时,因为使用了@Primary注解,所以不需要使用@Qualifier()注解来指定名字。

@Configuration
public class ChainedTransactionManagerConfig {
    //实现链式事务,
    @Bean(name = "chainedTransactionManager")
    public ChainedTransactionManager chainedTransactionManager(PlatformTransactionManager platformTransactionManager,
                                                               @Qualifier("xxxTransactionManager") PlatformTransactionManager xxxPlatformTransactionManager) {
        return new ChainedTransactionManager(platformTransactionManager, xxxPlatformTransactionManager);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读