springboot + druid + mybatis + mysql + multi-source data transaction management

springboot + druid + mybatis + mysql + multi-source data transaction management

Distributed Transaction Solutions in java is JTA (ie Java Transaction API); springboot official offers Atomikos or Solutions Bitronix of; in fact, many companies are in most cases the way the message queue that implement distributed transactions. Here it is Atomikos share a simple transaction management.

Project Dependencies

pom.xml added springboot related dependent atomikos of:

<!--分布式事务管理器-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-jta-atomikos</artifactId>
     </dependency>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <!--这里最好要5.1.47之后的版本-->
         <version>5.1.47</version>
     </dependency>

application.properties profile database-related information:

#数据库1
spring.datasource.druid.one.url=jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.one.username=root
spring.datasource.druid.one.password=123456

#数据库2
spring.datasource.druid.two.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.two.username=root
spring.datasource.druid.two.password=123456

Java configuration creates two categories, read the above information on two databases:

@ConfigurationProperties(prefix = "spring.datasource.druid.one")
public class DsOneProperties {
    private String username;
    private String password;
    private String url;
    //这里省掉Set和get方法
}
@ConfigurationProperties(prefix = "spring.datasource.druid.two")
public class DsTwoProperties {
    private String username;
    private String password;
    private String url;
    //这里省掉Set和get方法
}

In SpringBoot project started classes with the comment, when you start, it loads information

@EnableConfigurationProperties(value = {DsOneProperties.class, DsTwoProperties.class})

Create a master database configuration class MyBatisConfigOne:

@Configuration//声明该类是一个配置类
@MapperScan(basePackages = "com.lwh.mybatistest.mapper", sqlSessionFactoryRef = "sqlSessionFactory1", sqlSessionTemplateRef = "sqlSessionTemplate1")
//扫描的包是com.lwh.mybatistest.mapper
public class MyBatisConfigOne {
    // 配置主数据源
    @Primary
    @Bean
    public DataSource dsOne(DsOneProperties dsOneProperties) throws SQLException {
        //配置XA协议数据源,从配置文件中读取相应属性
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(dsOneProperties.getUrl());
        mysqlXaDataSource.setPassword(dsOneProperties.getPassword());
        mysqlXaDataSource.setUser(dsOneProperties.getUsername());
        //将本地事务注册到Atomikos全局事务
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("dsOne");
        return xaDataSource;
    }

    @Primary
    @Bean(name = "sqlSessionFactory1")
    public SqlSessionFactory SqlSessionFactory1(@Qualifier("dsOne") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    @Primary
    @Bean(name = "sqlSessionTemplate1")
    public SqlSessionTemplate SqlSessionTemplate1(
            @Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

In accordance with the above configuration database master classes, created from a configuration database categories:

@Configuration
@MapperScan(basePackages = "com.lwh.mybatistest.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2", sqlSessionTemplateRef = "sqlSessionTemplate2")
public class MyBatisConfigTwo {
    @Bean
    public DataSource dsTwo(DsTwoProperties dsTwoProperties) throws SQLException {
        //配置从数据源
        //配置XA协议数据源,从配置文件中读取相应属性
        MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
        mysqlXaDataSource.setUrl(dsTwoProperties.getUrl());
        mysqlXaDataSource.setPassword(dsTwoProperties.getPassword());
        mysqlXaDataSource.setUser(dsTwoProperties.getUsername());
        //将本地事务注册到Atomikos全局事务
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSource(mysqlXaDataSource);
        xaDataSource.setUniqueResourceName("dsTwo");
        return xaDataSource;
    }

    @Bean(name = "sqlSessionFactory2")
    public SqlSessionFactory SqlSessionFactory2(@Qualifier("dsTwo") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }


    @Bean(name = "sqlSessionTemplate2")
    public SqlSessionTemplate SqlSessionTemplate2(
            @Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

Create a simple controller test class:

@RestController
@RequestMapping("/book")
public class BookController {
    @Autowired
    BookService bookService;

    @Autowired
    BookService2 bookService2;

    @GetMapping("/add1")
    @Transactional
    public String addBook() {
        Book book = new Book();
        book.setBookname("测试");
        book.setAuthor("test:01");
        System.out.println("数据库1:>>>>");
        bookService.addBook(book);
        System.out.println("数据库2:>>>>");
        bookService2.addBook(book);
        return "测试add1操作成功!";
    }
    
    @GetMapping("/add2")
    @Transactional
    public String addBook2() {
        Book book = new Book();
        book.setBookname("测试add2");
        book.setAuthor("test:01");
        System.out.println("数据库1:>>>>");
        bookService.addBook(book);
        int a = 10 / 0;
        System.out.println("数据库2:>>>>");
        bookService2.addBook(book);
        return "测试add2操作成功!";
    }
}

Service class, is a simple insertion method, call mapper:

@Service
public class BookService {

    @Autowired
    BookMapper bookMapper;

    public void addBook(Book book) {
        bookMapper.insertSelective(book);
    }
}

There springboot default transaction manager, so there is no configuration, you can use the default, if you have special needs, you can create your own transaction manager itself.
The simplest atomikos plug on the configuration finished, the configuration information is relatively simple, the students want to study in depth, you can refer to the official documents.

Guess you like

Origin www.cnblogs.com/lwhsummer/p/11241774.html