一、下載與運行
本文使用 Seata 1.1.0:https://github.com/seata/seata/releases
Windows 環境下雙擊 bin/seata-server.bat 啟動 Seata Server
二、結合 MyBatis 使用
以 Service1 為例
2.1 添加引用
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
2.2 添加配置
2.2.1 registry.conf
放置在 resources 目錄,內容詳見代碼,均采用了默認配置
2.2.2 file.conf
放置在 resources 目錄,內容詳見代碼,均采用了默認配置
2.2.3 yml 配置
spring:
cloud:
alibaba:
seata:
tx-service-group: my_test_tx_group
注意:
file.conf 中 vgroup_mapping 的 key 值為 my_test_tx_group:
service {
vgroup_mapping.my_test_tx_group = "default"
}
則 yml 中 tx-service-group 的值也必須為 my_test_tx_group;如果 vgroup_mapping 的 key 值改為 abcdefg,則 yml 中 tx-service-group 的值也必須為 abcdefg,即這兩個值必須保持一致,否則會報錯:
no available service 'null' found, please make sure registry config correct
2.2.4 添加數據源配置
@Configuration
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/*.xml"));
return factoryBean.getObject();
}
}
在2.2.0.RELEASE及以后,數據源代理自動實現了,不需要再手動去配置一個代理類,官方文檔還需要配置 DataSourceProxy 應該是文檔沒有及時更新
2.2.5 添加 undo_log 表
在業務相關的數據庫中添加 undo_log 表,用於保存需要回滾的數據
CREATE TABLE `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`branch_id` BIGINT(20) NOT NULL,
`xid` VARCHAR(100) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT(11) NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8
2.3 使用
添加 @GlobalTransactional 注解即可
@Service
public class BusinessServiceImpl implements BusinessService {
@Reference
private StorageService storageService;
@Reference
private OrderService orderService;
@GlobalTransactional
@Override
public void purchase(Order order) throws Exception {
storageService.deduct(order.getCommodityCode(), order.getCount());
orderService.create(order);
}
}
三、結合 MyBatis-Plus 使用
與在 MyBatis 中使用類似,區別在於數據源的配置
3.1 錯誤配置
@Configuration
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
// @Bean
// public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
// SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
// factoryBean.setDataSource(dataSource);
// factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
// .getResources("classpath*:/mapper/*.xml"));
// return factoryBean.getObject();
// }
@Bean
@ConfigurationProperties(prefix = "mybatis-plus")
public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
// 這里用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否則 MyBatisPlus 不會生效
MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
mybatisSqlSessionFactoryBean.setDataSource(dataSource);
mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/mapper/*.xml"));
return mybatisSqlSessionFactoryBean;
}
}
上面配置是參考 seata-samples 中的配置,雖然可以正常使用,但是造成 MyBatis-Plus 的插件如分頁等不生效
3.2 正確配置
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
}
僅配置 DataSource 即可
完整代碼:GitHub
Seata 1.1.0 及之后版本支持直接在 application.yml 添加配置,可以替換掉 registry.conf 和 file.conf,本人暫未測試
參考