一、pom.xml里添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<version>2.6.6</version>
</dependency>
二、添加TransactionManagerConfig.class
package org.jeecg.modules.wms.config;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.springframework.context.annotation.*;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
@Configuration
@ComponentScan
@EnableTransactionManagement
public class TransactionManagerConfig {
@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
return userTransactionImp;
}
@Bean(name = "atomikosTransactionManager")
public TransactionManager atomikosTransactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
@Bean(name = "jta-transaction-manager")
@DependsOn({"userTransaction", "atomikosTransactionManager"})
@Primary
public PlatformTransactionManager transactionManager() throws Throwable {
return new JtaTransactionManager(userTransaction(), atomikosTransactionManager());
}
}
三、添加 DynamicDataSourceProviderImpl.class
package org.jeecg.modules.wms.config;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.mysql.cj.jdbc.MysqlXADataSource;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Service
@Primary
public class DynamicDataSourceProviderImpl implements DynamicDataSourceProvider {
/**
* 配置文件数据的松散绑定
*/
private final DynamicDataSourceProperties properties;
public DynamicDataSourceProviderImpl(DynamicDataSourceProperties properties) {
this.properties = properties;
}
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSourceProperty> dataSourcePropertiesMap = properties.getDatasource();
Map<String, DataSource> dataSourceMap = new HashMap<>(dataSourcePropertiesMap.size() * 2);
for (Map.Entry<String, DataSourceProperty> item : dataSourcePropertiesMap.entrySet()) {
String poolName = item.getKey();
DataSourceProperty dataSourceProperty = item.getValue();
dataSourceProperty.setPoolName(poolName);
// 接受数据源配置 并创建AtomikosDataSourceBean
dataSourceMap.put(poolName, createDataSource(dataSourceProperty));
}
return dataSourceMap;
}
/**
* 创建数据源
*
* @param dataSourceProperty 数据源信息
* @return 数据源
*/
private DataSource createDataSource(DataSourceProperty dataSourceProperty) {
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
mysqlXaDataSource.setUrl(dataSourceProperty.getUrl());
mysqlXaDataSource.setPassword(dataSourceProperty.getPassword());
mysqlXaDataSource.setUser(dataSourceProperty.getUsername());
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setMinPoolSize(5);
xaDataSource.setBorrowConnectionTimeout(60);
xaDataSource.setMaxPoolSize(20);
xaDataSource.setXaDataSourceClassName(dataSourceProperty.getDriverClassName());
xaDataSource.setTestQuery("SELECT 1 FROM DUAL");
xaDataSource.setUniqueResourceName(dataSourceProperty.getPoolName());
return xaDataSource;
}
}
四、应用
在需要管理多数据源事务的方法上使用@Transactional注解时,搭配上transactionManager = "jta-transaction-manager",其中的jta-transaction-manager是PlatformTransactionManager 对象注入为Bean时的name值,相关代码在TransactionManagerConfig.class中
// 多数据源事务处理
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "jta-transaction-manager")
public Boolean xxxxx(Integer orderId, Integer orderStatus) {...}