springBoot+atomikos实现分布式事务

一、前言

先把今天学习的内容记录一下,这是个插播,后面继续redis,嘿嘿。今天来聊聊springBoot的基础知识。

二、springBoot+atomikos实现分布式事务

我们先来看看应用场景,假设我们项目需要访问多个数据库,那事务怎么管理呢。那atomikos做的事情其实就是把所有数据源的事务统一管理起来。下面我们来看看怎么实现。

首先引入依赖。


	org.springframework.boot
	spring-boot-starter-jta-atomikos

然后配置数据源,我这里有2个数据库(ruan和youxianqi),你有多少就加多少。

spring:
###数据库配置
  datasource1:
    url: jdbc:mysql://localhost:3306/ruan
    username: root
    password:
    minPoolSize: 3
    maxPoolSize: 25
    maxLifetime: 20000
    borrowConnectionTimeout: 30
    loginTimeout: 30
    maintenanceInterval: 60
    maxIdleTime: 60
    testQuery: select 1
    driverClassName: com.mysql.jdbc.Driver
  datasource2:
      url: jdbc:mysql://localhost:3306/youxianqi
      username: root
      password:
      minPoolSize: 3
      maxPoolSize: 25
      maxLifetime: 20000
      borrowConnectionTimeout: 30
      loginTimeout: 30
      maintenanceInterval: 60
      maxIdleTime: 60
      testQuery: select 1
      driverClassName: com.mysql.jdbc.Driver

然后创建DBConfig1和DBConfig2,这两个实体类就是存放两个数据源的数据的。

package com.cgb.config;


import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "spring.datasource1")
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;

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getMinPoolSize() {
		return minPoolSize;
	}

	public void setMinPoolSize(int minPoolSize) {
		this.minPoolSize = minPoolSize;
	}

	public int getMaxPoolSize() {
		return maxPoolSize;
	}

	public void setMaxPoolSize(int maxPoolSize) {
		this.maxPoolSize = maxPoolSize;
	}

	public int getMaxLifetime() {
		return maxLifetime;
	}

	public void setMaxLifetime(int maxLifetime) {
		this.maxLifetime = maxLifetime;
	}

	public int getBorrowConnectionTimeout() {
		return borrowConnectionTimeout;
	}

	public void setBorrowConnectionTimeout(int borrowConnectionTimeout) {
		this.borrowConnectionTimeout = borrowConnectionTimeout;
	}

	public int getLoginTimeout() {
		return loginTimeout;
	}

	public void setLoginTimeout(int loginTimeout) {
		this.loginTimeout = loginTimeout;
	}

	public int getMaintenanceInterval() {
		return maintenanceInterval;
	}

	public void setMaintenanceInterval(int maintenanceInterval) {
		this.maintenanceInterval = maintenanceInterval;
	}

	public int getMaxIdleTime() {
		return maxIdleTime;
	}

	public void setMaxIdleTime(int maxIdleTime) {
		this.maxIdleTime = maxIdleTime;
	}

	public String getTestQuery() {
		return testQuery;
	}

	public void setTestQuery(String testQuery) {
		this.testQuery = testQuery;
	}

}

然后创建两个数据源RuanMyBatisConfig和YouMyBatisConfig,注意@Primary注解只能有一个。

package com.cgb.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.cgb.config.DBConfig1;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;

@Configuration
@MapperScan(basePackages = "com.cgb.ruan", sqlSessionTemplateRef = "testSqlSessionTemplate")
public class RuanMyBatisConfig {

	// 配置数据源
	@Primary
	@Bean(name = "dataSource1")
	public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
		MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
		mysqlXaDataSource.setUrl(testConfig.getUrl());
		mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
		mysqlXaDataSource.setPassword(testConfig.getPassword());
		mysqlXaDataSource.setUser(testConfig.getUsername());
		mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

		AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
		xaDataSource.setXaDataSource(mysqlXaDataSource);
		xaDataSource.setUniqueResourceName("dataSource1");

		xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
		xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
		xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
		xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
		xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
		xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
		xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
		xaDataSource.setTestQuery(testConfig.getTestQuery());
		return xaDataSource;
	}

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

	@Bean(name = "testSqlSessionTemplate")
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

其实在多个数据源的时候,我们怎么去指定数据库呢?

其中一个做法是写注解,表明使用哪个数据库,但是这种是不是很麻烦。最好的做法是分包管理:

springBoot+atomikos实现分布式事务_第1张图片

还没完呢,我们还需要在入口添加2个注解。

springBoot+atomikos实现分布式事务_第2张图片

好啦,大功告成,我们来看看效果吧。

springBoot+atomikos实现分布式事务_第3张图片

我们发现控制台打印添加学生成功,好我们看看数据库里有没有数据呢?

springBoot+atomikos实现分布式事务_第4张图片

毫无疑问是没有的,说明事务起作用了。那我们把那行异常代码注释掉,再看看效果。成功了,去看看数据库有没有呢。

springBoot+atomikos实现分布式事务_第5张图片

springBoot+atomikos实现分布式事务_第6张图片springBoot+atomikos实现分布式事务_第7张图片

ojbk,想想同时操作多个数据库,是不是很爽啊,哈哈哈。

 

你可能感兴趣的:(java)