社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
程序猿学社的GitHub,欢迎Star
https://github.com/ITfqyd/cxyxs
本文已记录到github,形成对应专题。
前一篇文章,我们已经实现了通过springboot+MP实现多数据源,实际上一章的代码,如果一个方法中操作多个数据源,如果中间出现异常,可能会存在一个入库成功,另外一个入库失败的问题。而没有保证多个数据源事务的一致性。、
继续在TestController类上加上如下代码,两个库,为了方便,我们就记录为test1和test2
@ApiOperation("同时向test1和test2中插入数据,增加指定某个事务的代码,并故意在代码中报错")
@PostMapping("/saveEmp4")
@Transactional(value = "test2TransactionManager")
public String saveEmp4(Emp emp) {
int insert = empMapper1.insert(emp);
insert = empMapper2.insert(emp);
//故意报错
String str= null;
System.out.println(str.toString()); //这里会报错
if(insert > 0){
return "插入成功";
}else{
return "插入失败";
}
};
输入http://localhost:8080/swagger-ui.html
点击try it out 运行。
给一个小提示,注意看清楚,配置的事务是test2TransactionManager
大家觉得test1和test2这两个库的emp表,会有什么变化?
有不少社友的答案,是不是test1和test2都不插入数据。
话不多说,检查一波数据库的身体
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cloudtech</groupId>
<artifactId>moredatasource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>moredatasource</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 增加thymeleaf坐标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!--swagger2-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>spring-boot-starter-swagger</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<!--MP插件,简化sql操作-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<!--swagger2-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>spring-boot-starter-swagger</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<!--jta+atomikos依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<!--解决编译后,xml文件没有过去的问题-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>include</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server:
port: 8888
spring:
datasource:
test1:
url: jdbc:mysql://localhost:3306/pro?useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
username: root
password: root
test2:
url: jdbc:mysql://localhost:3306/pro1?useUnicode=true&characterEncoding=utf8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
username: root
password: root
mybatis-plus:
configuration:
##打印sql日志,本地测试使用,生产环境不要使用,注意、注意、注意
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
####扫描swagger注解
swagger:
base-package: com.cxyxs
package com.cxyxs.moredatasource.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import org.omg.CORBA.IDLType;
/**
* Description:
* Author: 程序猿学社
* Date: 2020/3/7 12:03
* Modified By:
*/
@Data
public class Emp {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Integer age;
}
package com.cxyxs.moredatasource.test1.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cxyxs.moredatasource.entity.Emp;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Description:
* Author: 程序猿学社
* Date: 2020/3/7 12:01
* Modified By:
*/
@Repository
public interface EmpMapper1 extends BaseMapper<Emp>{
@Select("select * from emp")
public List<Emp> selectList();
/**
* 测试mapper
* @return
*/
public List<Emp> getAll();
}
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxyxs.moredatasource.test1.dao.EmpMapper1">
<!-- 根据区域名称获取区域代码-->
<select id="getAll" resultType="com.cxyxs.moredatasource.entity.Emp">
select * from emp
</select>
</mapper>
package com.cxyxs.moredatasource.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* Description:V2.0版本的代码
* Author: 程序猿学社
* Date: 2020/3/14 1:20
* Modified By:
*/
@ConfigurationProperties(prefix="spring.datasource.test1")
@Data
public class Test1Config {
private String url;
private String username;
private String password;
}
package com.cxyxs.moredatasource.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* Description:V2.0版本的代码
* Author: 程序猿学社
* Date: 2020/3/14 1:20
* Modified By:
*/
@ConfigurationProperties(prefix="spring.datasource.test2")
@Data
public class Test2Config {
private String url;
private String username;
private String password;
}
package com.cxyxs.moredatasource;
import com.cxyxs.moredatasource.config.Test1Config;
import com.cxyxs.moredatasource.config.Test2Config;
import com.spring4all.swagger.EnableSwagger2Doc;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.cxyxs"})
@EnableSwagger2Doc
@EnableConfigurationProperties(value = { Test1Config.class, Test2Config.class })
public class MoredatasourceApplication {
public static void main(String[] args) {
SpringApplication.run(MoredatasourceApplication.class, args);
}
}
package com.cxyxs.moredatasource.config;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.mysql.cj.jdbc.MysqlXADataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
@MapperScan(basePackages= {"com.cxyxs.moredatasource.test1.dao"},sqlSessionFactoryRef="test1SqlSessionFactory")
public class DataSourceConfigPlus1 {
// 配置数据源
@Bean("test1DataSource")
public DataSource testDataSource (Test1Config testConfig) throws SQLException {
//表示使用的是mysql数据库
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
mysqlXaDataSource.setUrl(testConfig.getUrl());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(testConfig.getPassword());
mysqlXaDataSource.setUser(testConfig.getUsername());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
//Atomikos负责管理所有的事务
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("test1DataSource");
return xaDataSource;
}
@Bean(name = "test1SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource,@Qualifier("test1PaginationInterceptor") PaginationInterceptor paginationInterceptor)
throws Exception {
//注意,这里引入的事MP的工厂,而不是mybatis的工厂SqlSessionFactoryBean
MybatisSqlSessionFactoryBean bean=new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
//引入Mapper.xml文件的位置
Resource[] resources = new PathMatchingResourcePatternResolver()
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_16855077/article/details/104852632
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!