spring boot+atomikos+mybatis+druid分布式事务实现
druid
阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
项目地址:https://gitcode.com/gh_mirrors/druid/druid
免费下载资源
·
配置数据源
新建配置类DataSourceConfig:
public class DataSourceConfig {
private static final String PRIMARY_MAPPER_BASE_PACKAGE = "io.github.yidasanqian.mapper.master";
private static final String BUSINESS_MAPPER_BASE_PACKAGE = "io.github.yidasanqian.mapper.business";
private static final String DATASOURCE_DRUID_PROPERTIES = "datasource/druid.properties";
private static final String DATASOURCE_DRUID_PRIMARY_PROPERTIES = "datasource/druid-primary.properties";
private static final String DATASOURCE_DRUID_BUSINESS_PROPERTIES = "datasource/druid-business.properties";
private static final String CLASSPATH_MAPPER_XML = "classpath:mapper/*/*.xml";
/**
* druid 公共配置
*/
private static Properties commonProperties;
static {
commonProperties = new Properties();
InputStream in = DataSourceConfig.class.getClassLoader().getResourceAsStream(DATASOURCE_DRUID_PROPERTIES);
try {
commonProperties.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Properties loadDruidProperties(String path) throws IOException {
Properties properties = new Properties();
InputStream in = getClass().getClassLoader().getResourceAsStream(path);
properties.load(in);
for (Map.Entry<Object, Object> entry : commonProperties.entrySet()) {
properties.setProperty(entry.getKey().toString(), entry.getValue().toString());
}
return properties;
}
/**
* 设置数据源
*
* @return
* @throws IOException
*/
@Primary
@Bean
public AtomikosDataSourceBean primaryDataSource() throws IOException {
return getAtomikosDataSourceBean(DATASOURCE_DRUID_PRIMARY_PROPERTIES);
}
@Bean
public AtomikosDataSourceBean businessDataSource() throws IOException {
return getAtomikosDataSourceBean(DATASOURCE_DRUID_BUSINESS_PROPERTIES);
}
private AtomikosDataSourceBean getAtomikosDataSourceBean(String dataSourceProperties) throws IOException {
Properties properties = loadDruidProperties(dataSourceProperties);
AtomikosDataSourceBean dataSourceBean = new AtomikosDataSourceBean();
// 配置DruidXADataSource
DruidXADataSource xaDataSource = new DruidXADataSource();
xaDataSource.configFromPropety(properties);
// 设置置AtomikosDataSourceBean XADataSource
dataSourceBean.setXaDataSource(xaDataSource);
return dataSourceBean;
}
/**
* 设置{@link SqlSessionFactoryBean}的数据源
* @param primaryDataSource 主数据源
* @return
*/
@Primary
@Bean
public SqlSessionFactoryBean primarySqlSessionFactoryBean(@Qualifier("primaryDataSource") AtomikosDataSourceBean primaryDataSource) {
return getSqlSessionFactoryBean(primaryDataSource);
}
@Bean
public SqlSessionFactoryBean businessSqlSessionFactoryBean(@Qualifier("businessDataSource") AtomikosDataSourceBean businessDataSource) {
return getSqlSessionFactoryBean(businessDataSource);
}
private SqlSessionFactoryBean getSqlSessionFactoryBean(AtomikosDataSourceBean dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(CLASSPATH_MAPPER_XML));
} catch (IOException e) {
throw new RuntimeException(e);
}
return sqlSessionFactoryBean;
}
/**
* 搜索{@link DataSourceConfig#PRIMARY_MAPPER_BASE_PACKAGE} 包下的Mapper接口,并且将这些接口
* 交由{@link MapperScannerConfigurer#sqlSessionFactoryBeanName} 属性设置的SqlSessionFactoryBean管理
* @return
*/
@Bean
public MapperScannerConfigurer primaryMapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage(PRIMARY_MAPPER_BASE_PACKAGE);
mapperScannerConfigurer.setSqlSessionFactoryBeanName("primarySqlSessionFactoryBean");
return mapperScannerConfigurer;
}
/**
* 搜索{@link DataSourceConfig#BUSINESS_MAPPER_BASE_PACKAGE} 包下的Mapper接口,并且将这些接口
* 交由{@link MapperScannerConfigurer#sqlSessionFactoryBeanName} 属性设置的SqlSessionFactoryBean管理
* @return
*/
@Bean
public MapperScannerConfigurer businessMapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage(BUSINESS_MAPPER_BASE_PACKAGE);
mapperScannerConfigurer.setSqlSessionFactoryBeanName("businessSqlSessionFactoryBean");
return mapperScannerConfigurer;
}
}
代码上都有注释,如有疑问,评论指出。
代码实现
结构:
两个Mapper接口定义一样的save
方法
service实现类DemoServiceImpl
:
@Transactional(rollbackFor = Exception.class)
@Service
public class DemoServiceImpl implements DemoService {
private final Logger log = LoggerFactory.getLogger(getClass());
@Resource
private MasterDemoMapper masterDemoMapper;
@Resource
private BusinessDemoMapper businessDemoMapper;
/**
* 正常测试分布式事务
*
* @return
* @throws Exception
*/
@Override
public int save() throws Exception {
log.info("save");
Demo dsDemo = new Demo();
dsDemo.setName("xa事务测试");
int row = masterDemoMapper.save(dsDemo);
log.info("保存之后");
Demo dsDemo1 = new Demo();
dsDemo1.setName("xa事务测试2");
int row2 = businessDemoMapper.save(dsDemo1);
return row + row2;
}
/**
* 测试分布式事务回滚
* @return
* @throws Exception
*/
@Override
public int save2() throws Exception {
log.info("save2");
Demo dsDemo = new Demo();
dsDemo.setName("xa事务回滚测试");
int row = masterDemoMapper.save(dsDemo);
log.info("保存之后异常");
int a = 1 / 0;
Demo dsDemo1 = new Demo();
dsDemo1.setName("xa事务回滚测试2");
int row2 = businessDemoMapper.save(dsDemo1);
return row + row2;
}
}
DemoController:
@RestController
public class DemoController {
@Resource
private DemoService dsService;
@RequestMapping("/testXaDatasource")
public String testXaDatasource() {
int result = 0;
try {
result = dsService.save();
} catch (Exception e) {
e.printStackTrace();
}
return String.valueOf(result);
}
@RequestMapping("/testXaDatasource2")
public String testXaDatasource2() {
int result = 0;
try {
result = dsService.save2();
} catch (Exception e) {
e.printStackTrace();
}
return String.valueOf(result);
}
}
访问http://localhost:8080/testXaDatasource返回2,表明多数据源及分布式事务可用。
访问http://localhost:8080/testXaDatasource2返回0,表明分布式事务回滚可用
源码地址
https://gitee.com/yidasanqian/spring-boot-distributed-transaction-demo.git
GitHub 加速计划 / druid / druid
3
3
下载
阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
最近提交(Master分支:5 个月前 )
f95350b3 - 4 小时前
cb6f3ac7 - 2 天前
更多推荐
已为社区贡献3条内容
所有评论(0)