SpringCloudAlibaba-18-seata分布式事务问题回显

前言

本节介绍SpringCloudAlibaba中分布式事务解决方案seta,首先我们不介绍seta,我们先模拟分布式事务这个问题。

内容

我们以案例出发,支付场景案例如下:

a.首先支付请求进来以后,经过我们的biz-service(前面的业务处理)对参数进行校验,校验完之后调用我们的订单服务:order-service统一下单,下单完之后,调用我们的支付服务pay-service去调用三方接口,在这个地方:order-service和pay-service都会操作自己的数据库,操作完之后通过biz-service给用户返回一个请求。那么这里有三个微服务,本节我们就实现这3个微服务。

1.创建3个服务

  1. 1.创建3个服务
  2. 2.修改对应端口为上图所示
  3. 3.3个服务创建完毕,我们需要让order(alibaba-order)和pay(alibaba-pay)服务能够操作单独的数据库。
  4. 4.数据库脚本为:
1
2
3
4
CREATE TABLE `order/pay` (
`id` int(11) DEFAULT NULL,
`username` varchar(20) DEFAULT NULL COMMENT '用户名'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  1. 5.操作数据库插入数据
1
2
3
4
5
6
7
8
9
10
@Service
public class OrderService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Transactional
public void save(){
jdbcTemplate.update("INSERT INTO `order`( `username`) VALUES ('123');");
}
}
```

@Service
public class PayService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Transactional
public void save(){
jdbcTemplate.update(“INSERT INTO pay( username) VALUES (‘123’);”);
}
}

1
2
6. 6.order/pay-service服务提供给biz-service访问的接口

@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping(“/order”)
public String order(){
orderService.save();
return “success”;
}
}

1
2

@RestController
public class PayController {
@Autowired
private PayService payService;
@GetMapping(“/pay”)
public String pay(){
payService.save();
return “success”;
}
}

1
2
3
4
5
6
#### 2.biz服务调用其他服务
我们使用spring自带的RestTemplate模板
1. 1.创建service

@Service
public class BizService {
@Autowired
private RestTemplate restTemplate;
@Transactional
public void biz(){
//order
restTemplate.getForObject(“http://127.0.0.1:8020/order",String.class);
//pay
restTemplate.getForObject(“http://127.0.0.1:8030/pay",String.class);
}
}

1
2
3
4
2. 2.创建controller

@RestController
public class BizController {
@Autowired
private BizService bizService;
@GetMapping(“/biz”)
public String biz(){
bizService.biz();
return “success”;
}
}
```

  1. 3.重启3个服务
    我们访问:http://127.0.0.1:8010/biz
    结果返回:success
    查看数据库表时候发现我们表中插入了数据。

3.分布式事务出现情况

我们分析一下分布式事务会出现在什么情况下?
我们在biz服务调用其他两个服务的时候添加以下语句: int i = 1 / 0; 让其报错,这个时候pay/order服务会回滚吗?不会回滚的,因为pay/order是不同的jvm。本地事务是管不到其他jvm里面的(进程之间事务不具有传递性)。

我们重启:biz-service,然后访问:http://127.0.0.1:8010/biz
此时pay/order服务已经插入了数据

毕业于<br>相信技术可以改变人与人之间的生活<br>码农一枚