springboot+jta+atomikos分布式多数据源事务管理 (SQLserver)

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 在我上一篇博客的项目基础上做更改springboot多数据源分包式实现首先我们来试一下没有更改的情况下

在我上一篇博客的项目基础上做更改

springboot多数据源分包式实现

首先我们来试一下没有更改的情况下

1.@Service
public class User2Service {
  @Autowired
  private User2Mapper mapper2;
  @Autowired
  private User2Mapper mapper1;
  @Transactional
  public void insert() {
    mapper1.insert();
    int a = 1/0;
    mapper2.insert();
  }
}
@Repository
public interface User1Mapper{
  @Insert("insert into user_demo values('事务管理','1')")
  public void insert();
}
@Repository
public interface User2Mapper {
  @Insert("insert into user_demo values('事务管理','2')")
  public void insert();
}

在User2Service中同时对User1Mapper 和User2Mapper进行事务管理,在中间的除零异常出现后,数据还是被保存到了数据库,但是只是UserMapper2的数据被保存到了数据库,UserMapper1的数据被回滚,这种情况下默认是只对@Primary的数据源进行事务管理



那我们就把事务管理交给atomikos


首先application.properties配置文件重新写一下,依赖引入一下

sqlserver.datasource.test1.url=jdbc:sqlserver://localhost:1433;DatabaseName=Test
sqlserver.datasource.test1.username=sa
sqlserver.datasource.test1.password=vhukze
sqlserver.datasource.test1.minPoolSize=3
sqlserver.datasource.test1.maxPoolSize=25
sqlserver.datasource.test1.maxLifetime=20000
sqlserver.datasource.test1.borrowConnectionTimeout=30
sqlserver.datasource.test1.loginTimeout=30
sqlserver.datasource.test1.maintenanceInterval=60
sqlserver.datasource.test1.maxIdleTime=60
sqlserver.datasource.test1.testQuery=select 1
#mybatis  配置文件
#sqlserver.datasource.test1.mapper-locations=classpath:mapper1/*.xml
#mybatis 对应的实体类
#sqlserver.datasource.test1.type-aliases-package=com.wangye.spbootjtaautomatic.model1
#sqlserver2
sqlserver.datasource.test2.url=jdbc:sqlserver://localhost:1433;DatabaseName=Test1
sqlserver.datasource.test2.username=sa
sqlserver.datasource.test2.password=vhukze
sqlserver.datasource.test2.minPoolSize=3
sqlserver.datasource.test2.maxPoolSize=25
sqlserver.datasource.test2.maxLifetime=20000
sqlserver.datasource.test2.borrowConnectionTimeout=30
sqlserver.datasource.test2.loginTimeout=30
sqlserver.datasource.test2.maintenanceInterval=60
sqlserver.datasource.test2.maxIdleTime=60
sqlserver.datasource.test2.testQuery=select 1
#mybatis  配置文件
#sqlserver.datasource.test2.mapper-locations=classpath:mapper2/*.xml
#mybatis 对应的实体类
#sqlserver.datasource.test2.type-aliases-package=com.wangye.spbootjtaautomatic.model2
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>

我这里没有建实体类也没有用配置文件 。

然后把之前的数据源配置类注释了 删了也行 我这里就注释了。

新建两个配置类

package com.vhukze.datasource;
import java.sql.SQLException;
import javax.sql.DataSource;
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 com.atomikos.jdbc.AtomikosDataSourceBean;
import com.microsoft.sqlserver.jdbc.SQLServerXADataSource;
import com.vhukze.config.DBConfig1;
/**
* @author zsz
* @version 
* @创建时间:2019年9月3日 上午9:31:28
*/
@Configuration
@MapperScan(basePackages="com.vhukze.test1",sqlSessionTemplateRef="test1SqlSessionTemplate")
public class TestMybatisConfig1 {
  @Primary
  @Bean(name="test1DataSource")
  public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
    SQLServerXADataSource sqlServerXADataSource = new SQLServerXADataSource();
    sqlServerXADataSource.setURL(testConfig.getUrl());
    sqlServerXADataSource.setUser(testConfig.getUsername());
    sqlServerXADataSource.setPassword(testConfig.getPassword());
    AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
    atomikosDataSourceBean.setXaDataSource(sqlServerXADataSource);
    atomikosDataSourceBean.setUniqueResourceName("test1DataSource");
    atomikosDataSourceBean.setMinPoolSize(testConfig.getMinPoolSize());
    atomikosDataSourceBean.setMaxPoolSize(testConfig.getMaxPoolSize());
    atomikosDataSourceBean.setMaxLifetime(testConfig.getMaxLifeTime());
    atomikosDataSourceBean.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeOut());
    atomikosDataSourceBean.setLoginTimeout(testConfig.getLoginTimeOut());
    atomikosDataSourceBean.setMaintenanceInterval(testConfig.getMaintenanceInterval());
    atomikosDataSourceBean.setMaxIdleTime(testConfig.getMaxIdleTime());
    atomikosDataSourceBean.setTestQuery(testConfig.getTestQuery());
    return atomikosDataSourceBean;
  }
  @Bean(name="test1SqlSessionFactory")
  public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception { 
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean.getObject();
  }
  @Bean(name="test1SqlSessionTemplate")
  public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { 
    return new SqlSessionTemplate(sqlSessionFactory);
  }
}

第二个就把这里面的test1和DBConfig1改成test2和DBConfig2 就好了,跟之前的配置类差不多,就是把DataSource交给atomikos管理了

然后创建一下里面需要用到的配置实体类DBConfig1和DBConfig2 在新建的一个config包下

package com.vhukze.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author zsz
* @version 
* @创建时间:2019年9月3日 上午9:55:23
*/
@ConfigurationProperties(prefix="sqlserver.datasource.test1")
public class DBConfig1 {
  private String url;
  private String username;
  private String password;
  private int minPoolSize;
  private int maxPoolSize;
  private int maxLifeTime;
  private int borrowConnectionTimeOut;
  private int loginTimeOut;
  private int maintenanceInterval;
  private int maxIdleTime;
  private String testQuery;
  get set 方法
}

这个跟上面一样    DBConfig2 就把注解里面的test1改成test2

在启动类添加扫描config包 还有一个什么开启配置文件 就把两个字节码文件给它就行

1.@SpringBootApplication
@ComponentScan(basePackages= {"com.vhukze.config","com.vhukze.controller","com.vhukze.test1.service","com.vhukze.test2.service","com.vhukze.datasource"})
@MapperScan({"com.vhukze.test1.mapper","com.vhukze.test2.mapper"})
@EnableConfigurationProperties(value = {DBConfig1.class,DBConfig2.class})
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

到这里就改完了配置,也没多麻烦。


启动项目访问映射路径------报错……


无法创建 XA 控制连接。错误:“找不到存储过程 'master..xp_sqljdbc_xa_init_ex'


这是因为sql server库的服务器没有配置XA事务和安装JDBC插件


解决步骤写在了另一篇博客中-->无法创建XA控制连接


而且我之前用的是公司服务器中的SQLserver,然后换成本机的了,但是不知道连接密码,解决办法


-->SQLserver改登录密码


都弄好之后测试成功,可以同时管理两个数据源的事务


相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
4月前
|
NoSQL Java 测试技术
字节二面:Spring Boot Redis 可重入分布式锁实现原理?
字节二面:Spring Boot Redis 可重入分布式锁实现原理?
163 1
|
2月前
|
Java 编译器 数据库
Spring Boot 整合 redisson 实现分布式锁
Spring Boot 整合 redisson 实现分布式锁
27 1
|
3天前
|
Java 关系型数据库 数据库
Spring Boot多数据源及事务管理:概念与实战
【4月更文挑战第29天】在复杂的企业级应用中,经常需要访问和管理多个数据源。Spring Boot通过灵活的配置和强大的框架支持,可以轻松实现多数据源的整合及事务管理。本篇博客将探讨如何在Spring Boot中配置多数据源,并详细介绍事务管理的策略和实践。
20 3
|
1天前
|
编解码 NoSQL Java
Springboot框架使用redisson实现分布式锁
Redisson是官方推荐的Java Redis客户端,提供丰富的功能,包括默认的分布式锁支持。它可以无缝替代Spring Boot 2.x的Letture客户端,不影响原有RedisTemplate和Redis Repository的使用。集成包括spring-boot-starter-data-redis和redisson-spring-boot-starter,后者需排除默认的redisson-spring-data-23以匹配Spring Data Redis v.2.2.x。
|
6天前
|
消息中间件 人工智能 Java
Spring Boot+RocketMQ 实现多实例分布式环境下的事件驱动
Spring Boot+RocketMQ 实现多实例分布式环境下的事件驱动
18 1
|
23天前
|
存储 关系型数据库 MySQL
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
|
2月前
|
druid Java 数据库连接
SpringBoot + Mybatis + Druid + PageHelper 实现多数据源分页
SpringBoot + Mybatis + Druid + PageHelper 实现多数据源分页
38 0
|
2月前
|
Java 数据库连接 数据库
Spring Boot整合MyBatis Plus集成多数据源轻松实现数据读写分离
Spring Boot整合MyBatis Plus集成多数据源轻松实现数据读写分离
28 2
|
2月前
|
Java BI 调度
Spring Boot 整合xxl-job实现分布式定时任务
XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 xxl是xxl-job的开发者大众点评的许雪里名称的拼音开头。
|
3月前
|
存储 Java 关系型数据库
springboot整合多数据源的配置以及动态切换数据源,注解切换数据源
springboot整合多数据源的配置以及动态切换数据源,注解切换数据源
76 0