Seata使用
使用seata进行分布式事务非常的简单,只是依赖于一个seata server服务,首先将服务启动,然后对微服务进行配置
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <exclusions> <exclusion> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>1.1.0</version> </dependency>
|
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| mybatis: config-location: classpath:mybatis/mybatis.cfg.xml type-aliases-package: com.zhanghe.study.springcloudalibaba.model mapper-locations: - classpath:mybatis/mapper/**/*.xml
spring: application: name: springcloudalibaba-seata-order cloud: sentinel: transport: dashboard: localhost:8080 port: 8719 alibaba: seata: tx-service-group: my_test_tx_group nacos: discovery: server-addr: localhost:8848 datasource: druid: username: root password: 123456 url: jdbc:mysql://localhost:3306/seata_order driver-class-name: com.mysql.jdbc.Driver feign: sentinel: enabled: true
|
将seata server中配置好的file.conf和registry.conf也要拷贝到项目的资源路径下
启动类
启动类要排除掉DataSourceAutoConfiguration,因为需要修改数据源,不使用默认的配置
1 2 3 4 5 6 7 8
| @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableDiscoveryClient @EnableFeignClients public class OrderApp { public static void main(String[] args) { SpringApplication.run(OrderApp.class,args); } }
|
数据源配置
这里要使用Seata的数据源进行代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| @Configuration @EnableConfigurationProperties({MybatisProperties.class}) public class DataSourceConfiguration {
@Bean @ConfigurationProperties(prefix = "spring.datasource.druid") public DataSource dataSource() { return new DruidDataSource(); }
@Bean public DataSourceProxy dataSourceProxy(DataSource dataSource) { return new DataSourceProxy(dataSource); }
@Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSourceProxy dataSourceProxy, MybatisProperties mybatisProperties) { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSourceProxy);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { Resource[] mapperLocaltions = resolver.getResources(mybatisProperties.getMapperLocations()[0]); bean.setMapperLocations(mapperLocaltions);
if (StringUtils.isNotBlank(mybatisProperties.getConfigLocation())) { Resource[] resources = resolver.getResources(mybatisProperties.getConfigLocation()); bean.setConfigLocation(resources[0]); } } catch (IOException e) { e.printStackTrace(); } return bean; } }
|
在业务方法上使用@GlobalTransactional注解进行标注全局事务
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @GlobalTransactional(name = "create-order",rollbackFor = Exception.class) public void create(Order order){ System.out.println("创建订单"); orderDao.addOrder(order);
System.out.println("扣减库存"); storageClient.decrease(order.getProductId(),order.getCount());
System.out.println("账户余额扣减"); accountClient.decrease(order.getUserId(),order.getMoney());
System.out.println("订单状态修改"); orderDao.updateStatus(order.getId(),order.getStatus()); }
|