maven依赖
点击查看代码
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
.yml文件及相关bean配置
.yml配置
点击查看代码
spring:
db1:
url: jdbc:mysql://localhost:3306/xiaotianxian?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=Asia/Shanghai
username: ***
password: ***
driver-class-name: com.mysql.cj.jdbc.Driver
db2:
url: jdbc:mysql://localhost:3306/xiaotianxian?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&serverTimezone=Asia/Shanghai
username: ***
password: ***
driver-class-name: com.mysql.cj.jdbc.Driver
数据源配置,有几个数据源配置几份
点击查看代码
package com.example.miniprojectdemo.common.atomiks;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.mysql.cj.jdbc.MysqlXADataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.StringJoiner;
/**
* @description:
* @author: wangqiang
* @create: 2022-11-21 13:32:29
*/
@Component(value = "db1")
@ConfigurationProperties(prefix = "spring.datasource.db1")
@MapperScan(basePackages = "com.example.miniprojectdemo.dao.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")
public class DB1 {
private String driverClassName;
private String url;
private String username;
private String password;
@Bean(name = "db1DataSource")
public DataSource dataSource() throws SQLException {
MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
mysqlXADataSource.setUrl(url);
mysqlXADataSource.setUser(username);
mysqlXADataSource.setPassword(password);
mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXADataSource);
xaDataSource.setUniqueResourceName("db1DataSource");
xaDataSource.setMaxPoolSize(20);
xaDataSource.setMinPoolSize(3);
return xaDataSource;
}
//配置数据源
@Bean(name = "db1SqlSessionFactory")
public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
//mapper.xml 的位置
Resource[] resources = pathMatchingResourcePatternResolver.getResources("classpath*:mappers/db1/*.xml");
factoryBean.setMapperLocations(resources);
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.example.miniprojectdemo.domain");//实体类别名
//防止pagehelper分页功能失效
/*MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
factoryBean.setPlugins(new Interceptor[]{interceptor});*/
return factoryBean.getObject();
}
@Bean(name = "db1SqlSessionTemplate")
public SqlSessionTemplate db1SqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
public DB1() {
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
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;
}
@Override
public String toString() {
return new StringJoiner(", ", DB1.class.getSimpleName() + "[", "]")
.add("driverClassName='" + driverClassName + "'")
.add("url='" + url + "'")
.add("username='" + username + "'")
.add("password='" + password + "'")
.toString();
}
}
事务配置,无论几个数据源只需要配置这一个
点击查看代码
package com.example.miniprojectdemo.common.atomiks;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
/**
* @description:
* @author: wangqiang
* @create: 2022-11-21 14:03:57
*/
@Configuration
public class TransactionManagerConf {
/**
* 不管有多少个数据源只要配置一个 TransactionManager
*/
@Bean(name = "atomikosTransactionManager")
public TransactionManager atomikosTransactionManager(){
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(10000);
return userTransactionImp;
}
@Bean(name = "transactionManager")
@DependsOn({"userTransaction", "atomikosTransactionManager"})
public PlatformTransactionManager transactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
TransactionManager atomikosTransactionManager = atomikosTransactionManager();
return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
}
}
使用方式
与普通事务管理相似,在业务方法上加上注解@Transactional,
点击查看代码
@Transactional
public void testAtomiksTs(User user){
user.setOpenId(UUID.randomUUID().toString().replace("-",""));
int i = userDao.insertDY(user);
logger.info("执行结果:{}", i);
user.setOpenId(UUID.randomUUID().toString().replace("-",""));
int i1 = db2UserDao.insertDY(user);
logger.info("执行结果:{}", i);
i = 1/0;
}
注意事项
oracle可能需要开启权限,若出现如下错误可尝试使用赋予权限解决
grant select on sys.dba_pending_transactions to USER_NAME;
grant select on sys.pending_trans$ to USER_NAME;
grant select on sys.dba_2pc_pending to USER_NAME;
grant execute on sys.dbms_system to USER_NAME
浙公网安备 33010602011771号