Spring Cloud Alibaba 06_使用 Seata实现分布式事务
创建 order 模块,选择:spring web、JDBC API 和 MySQL Driver
创建 pay 模块,选择:spring web、JDBC API 和 MySQL Driver
修改 order 和 pay 的父工程:
<parent>
<groupId>com.blu</groupId>
<artifactId>springcloudalibabademo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
创建数据库 order,创建表 orders,字段 id、username
创建数据库 pay,创建表 pay,字段 id、username
order 模块的 application.yml 配置文件:
server:
port: 8090
spring:
application:
name: order
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/order
username: root
password: 123456
pay 模块的 application.yml 配置文件
server:
port: 8100
spring:
application:
name: pay
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/pay
username: root
password: 123456
OrderService:
package com.blu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void save(){
this.jdbcTemplate.update("insert into orders(username) value ('张三')");
}
}
PayService:
package com.blu.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class PayService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void save(){
this.jdbcTemplate.update("insert into pay(username) value ('张三')");
}
}
OrderApplication:注册 RestTemplate
package com.blu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
OrderController:
package com.blu.controller;
import com.blu.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private RestTemplate restTemplate;
@GetMapping("save")
public String save(){
//创建订单
this.orderService.save();
int i = 1/0;
//支付
this.restTemplate.getForObject("http://localhost:8100/save",String.class);
return "success";
}
}
PayController:
package com.blu.controller;
import com.blu.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PayController {
@Autowired
private PayService payService;
@GetMapping("save")
public String save(){
this.payService.save();
return "success";
}
}
启动访问:http://localhost:8090/save 出现报错
检查数据库,发现 orders 表成功插入数据,但 pay 表没有,这就是 分布式异常
使用 Seata 实现分布式事务
seata-server 下载地址:https://github.com/seata/seata/releases
解压后,修改 registry.conf:
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = ""
cluster = "default"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "localhost"
namespace = ""
}
}
修改 nacos-config.txt:
service.vgroup_mapping.my_test_tx_group=default
service.vgroup_mapping.order=default
service.vgroup_mapping.pay=default
注:Windows系统无法直接执行.sh文件,需要使用git bash执行
sh nacos-config.sh 127.0.0.1
注:JDK 8 以上的环境无法启动 Seata Server
seata-server.bat -p 8020 -m file
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;
分别在 order 和 pay 数据库中执行以上sql来创建 undo_log 表(用于记录需要回滚的信息)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
注意这里的 DataSourceProxy 的包是 io.seata.rm.datasource.DataSourceProxy
DataSource 的包是 javax.sql.DataSource
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
return new JdbcTemplate(new DataSourceProxy(dataSource));
}
spring:
application:
name: order
cloud:
nacos:
config:
server-addr: localhost:8848
namespace: public
group: SEATA_GROUP
alibaba:
seata:
tx-service-group: ${spring.application.name}
spring:
application:
name: pay
cloud:
nacos:
config:
server-addr: localhost:8848
namespace: public
group: SEATA_GROUP
alibaba:
seata:
tx-service-group: ${spring.application.name}
至此,Seata 的环境就搭建完成了!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blucoding.blog.csdn.net/article/details/109388066
内容来源于网络,如有侵权,请联系作者删除!