美文网首页springbootspring 整合使用技术分享
SpringBoot2.x实现链式事务(分库事务)

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

作者: 小胖学编程 | 来源:发表于2020-11-30 17:27 被阅读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);
        }
    }
    

    相关文章

      网友评论

        本文标题:SpringBoot2.x实现链式事务(分库事务)

        本文链接:https://www.haomeiwen.com/subject/wstdwktx.html