开发者学堂课程【Spring Cloud 微服务架构设计与开发实战 :3.8 Spring Cloud Alibaba Seata 分布式事务】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/60/detail/1101
3.8 Spring Cloud Alibaba Seata 分布式事务
内容介绍
一、Seata 微服务分布式事务框架
二、Seata 微服务分布式架构图
三、Seata 微服务分布式事务框架实战
这节课讲如何结合 Spring Cloud 去使用阿里巴巴微服务分布式事务框架 Seata,Seata 是阿里云开发的重要解决方案,下面介绍相关特定。
一、Seata 微服务分布式事务框架
Seata 可以认为是尝试去支持不同微服务框架的事务性机制,而微服务本身是很难去支持分布式事务,这是一个很大的弱点,在于其协议,目前 Spring Cloud 默认使用协议是 http,这个协议本身并不支持事务特性,所谓企业级开发有很多重要的要求,但 Spring Cloud 是不支持的,而作为某些公司就会用到基于微服务的一些事务机制,这里提醒微服务架构中的事务绝大部分的都没有实现真正意义上事务的ACID 特性。
1、Spring Cloud Seata
Seata 早期名为 Fescar,是阿里巴巴开源的分布式事务框架,后面与项目Fast&EaSy 合并,变成更好用简单的分布式事务框架,不仅支持 Dubbo,Spring Cloud 等,包括其他的微服务分布式事务也是支持的。
2、阿里 Seata 发展路线图
如下面图 Seata 也在不断的迭代,这里注意在微服务架构中可以去不断的切换不同的主页,不断的升级改造。后面会提到具体这样使用,因为微服务架构中大部分做的都是消息补偿,比如做个消息中心店,发消息更新对面的服务,或者用定时针的这些机制用的更多,而因为性能问题使用分布式的更少。
二、Seata 微服务分布式架构图
1、电商交易场景(无事务分布式架构图)
一般模拟的场景为用户要购买,购买的话要生成订单,快递服务,抢购的时候还要库存问题,比如一个物品要买10件而库存只有5件,这里就要做判断,看是不是成功,这中间就要涉及到不同数据一次性判断问题,还要做数据的头部,包括同步积分,同步优惠券等一系列问题,这里面就会有微服务分布事务的问题出现,当然这个是在微服务架构中很难实现的,主要是靠 RPC 框架,RPC 主要在自己业务上用得更多,后面变成开源了,也是在微服务架构中比较重要的解决方案。
2、Seata 分布式事务架构图
当然这些只是了解不强迫使用,了解只是为了以后的架构设计多个选择,能更合理的技术选型而不是直接的做某个框架,架构设计要综合考虑,包括成本,需求等问题。
三、Seata 微服务分布式事务框架实战
1、Seata 分布式事务改造
实战的话框架的实现机制大部分都是补偿机制,虽然模拟了一个分布式事务协议,但不是真正意义上的,没有强制性去使用库,没有做分布式锁的概念,实际上是尝试插入数据,然后再删除,可以发现是通过逻辑上的特性代码来模拟一个真正的分布式事务。
简单的注解
@GlobalTransactional
直接标注在事务方法上即可
@GlobalTransactional
public void purchase(String userld, String
commodityCode, int orderCount) {
…
}
这里需要注意 GlobalTransactional 叫全局事务,设计模式上很像一些协议,包括JTA 事务这种框架,爬取几个库和做了一些什么操作都会有一个根事务,还有像事务管理器,资源管理器这些角色参与进来。这种叫强事务,严重会影响到系统的性能,因为有大量的协调事件加上长级事务锁、数据库的锁、资源的锁,所以会影响整个系统的优良性,而系统在事务这方面选择的走实物系统。
<dependency>
<groupld> io.seata </groupld>
<artifactld> seata-all </artifactld>
<version> ${seata.version} </version>
</dependency>
2、Seata 实战依赖
这个代码要加上 Seata 的依赖,也可以直接用但要考虑到兼容,因为阿里巴巴版本和 Spring Cloud 版本没有及时的跟进,可能会有1-2个版本的差异,那么包括现在演示的2.1,2.1,2.3提前做测试还可以用。这做依赖的时候可以用快速开发,里面也统一提供了一个甲方依赖包,配置到文件中就可以直接拉进依赖包。可以看下下面的代码,主要是做一个扩展,Seata 知识的几种模式实际都是在逻辑上通过模拟事务的场景,使用当中要慎重,因为实际上事务会有更多的消息通信,更多的协调工作,而且这里面肯定会影响到系统的性能。
<dependency>
<groupId>com. Alibaba
.
cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.1. RELEASE</version>
</dependency>
3、代码讲解
下面重点讲解下代码,Seata 这种分布事务需要注意一个问题,比如是在某一个微服务里面调用了其他接口的场景,服务是下单类的服务操作,接下来就是购买,购买就要生成一个订单,然后要调用支付的服务,库存的服务,这里模拟的一个交易的服务场景,代码如下:
SeateBusinessServicelmpl.java 中代码为
package com. alibaba.services;
import
i
o. seata. spring. annotation.GlobalTransactional;
public class SeataBusinessServiceImpl implements SeataBusinessServic
es
private StorageService storageService;
private OrderService orderService;
private PayService payService;
/
*
*
*购买,启动全局事务
*/
@GlobalTransactional
public void buy(String userId, String commodityCode, int orderCount)
// 1.订单微服务
orderService . create(userId, commodityCode, orderCount);
// 2.库存微服务
storageService . deduct( commodityCode, orderCount);
// 3.支付微服务
payService . deduct(userId, orderCount);
//4.其他微服务调用,快递服务,积分、优惠券等
}
如有订单的服务,实现接口,账号的实现,支付,仓库的实现,而在案例的代码中下单操作实际上接入了仓库 StorageService 的实现,订单 OrderService 的实现和支付 PayService 的实现,而如果要启动分布式事务的话就一定要有全局注解 @GlobalTransactional,下面在下订单的时候就要依次调用订单微服务,减库存,完成支付操作,当然也可以完成其他的,比如推送一个快递,积分,优惠券等,其他的微服务都可以一次性调用,但一般没有要求是不会这样做的,而会做逻辑性操作 try.catch,尝试去调用这个服务,只是说有这样一种框架多一个选择比没有好,而且知道他的机制模式和实现方法。