有来实验室|第一篇:Seata1.5.2版本部署和开源全栈商城订单支付业务实战(二)

简介: 有来实验室|第一篇:Seata1.5.2版本部署和开源全栈商城订单支付业务实战(二)

四. Seata 客户端搭建

1. Maven 依赖

   com.alibaba.cloud

   spring-cloud-starter-alibaba-seata

   

   

       

           io.seata

           seata-spring-boot-starter

       

   


   io.seata

   seata-spring-boot-starter

   1.5.2



2. undo_log 表

undo_log表脚本: https://github.com/seata/seata/blob/1.5.2/script/client/at/db/mysql.sql


-- for AT mode you must to init this sql for you business database. the seata server not need it.

CREATE TABLE IF NOT EXISTS `undo_log`

(

   `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',

   `xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',

   `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',

   `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',

   `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',

   `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',

   `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',

   UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)

) ENGINE = InnoDB

 AUTO_INCREMENT = 1

 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';


AT模式两阶段提交协议的演变:


一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。

二阶段:

提交异步化,非常快速地完成。

回滚通过一阶段的回滚日志进行反向补偿。

Seata的AT模式下之所以在第一阶段直接提交事务,依赖的是需要在每个RM创建一张undo_log表,记录业务执行前后的数据快照。


如果二阶段需要回滚,直接根据undo_log表回滚,如果执行成功,则在第二阶段删除对应的快照数据。


3. 客户端配置

微信图片_20230710090914.png


# Seata配置

seata:

 enabled: true

 # 指定事务分组至集群映射关系,集群名default需要与seata-server注册到Nacos的cluster保持一致

 service:

   vgroup-mapping:

     mall_tx_group: default

 # 事务分组配置

 tx-service-group: mall_tx_group

 registry:

   type: nacos

   nacos:

     application: seata-server

     # nacos 服务地址

     server-addr: 192.168.10.99:8848

     namespace:

     group: SEATA_GROUP


以上3点就是 Seata 客户端需要做的事项,下面就 Seata 如何实战应用进行展开详细说明。


五. Seata 实战

Seata 官网示例: http://seata.io/zh-cn/docs/user/quickstart.html


需求

用户购买商品订单支付的业务逻辑。整个业务逻辑由3个微服务提供支持:


商品服务:扣减商品库存。

订单服务:修改订单状态【已支付】。

会员服务:扣减账户余额。

架构图

微信图片_20230710090927.png


TM:事务管理器(有来实验室:laboratory)

RM:资源管理器(商城服务:mall-pms;会员服务:mall-ums;订单服务:mall-oms)

TC :事务协调者(Seata服务端:seata-server)

代码实现

有来实验室

实验室在“订单支付”案例中扮演的是【事务管理器】的角色,其工作内容是开始全局事务、提交或回滚全局事务。


按照 【第三节-Seata客户端搭建 】 在 laboratory 模块添加 Maven 依赖和客户端的配置。


订单支付关键代码片段(SeataServiceImpl#payOrderWithGlobalTx),通过注解 GlobalTransactional 开启全局事务,通过对商品 Feign 客户端和订单 Feign 客户端的调用完成订单支付的流程,这是全局事务开始的地方。



   /**

    * 订单支付(全局事务)

    */

   @GlobalTransactional

   public boolean payOrderWithGlobalTx(SeataForm seataForm) {


       log.info("========扣减商品库存========");

       skuFeignClient.deductStock(skuId, 1);


       log.info("========订单支付========");

       orderFeignClient.payOrder(orderId, ...);


       return true;

   }


商品服务

按照 【第三节-Seata客户端搭建 】 在 mall-pms 模块添加 Maven 依赖和客户端的配置,在 mall-pms 数据库创建 undo_log 表。


扣减库存关键代码:


   /**

    * 「实验室」扣减商品库存

    */

   public boolean deductStock(Long skuId, Integer num) {

       boolean result = this.update(new LambdaUpdateWrapper()

               .setSql("stock_num = stock_num - " + num)

               .eq(PmsSku::getId, skuId)

       );

       return result;

   }


订单服务

按照 【第三节-Seata客户端搭建 】 在 mall-oms 模块添加 Maven 依赖和客户端的配置,在 mall-oms 数据库创建 undo_log 表。


订单支付关键代码:


   /**

    * 「实验室」订单支付

    */

   public Boolean payOrder(Long orderId, SeataOrderDTO orderDTO) {


       Long memberId = orderDTO.getMemberId();

       Long amount = orderDTO.getAmount();


       // 扣减账户余额

       memberFeignClient.deductBalance(memberId, amount);


       // 【关键】如果开启异常,全局事务将会回滚

       Boolean openEx = orderDTO.getOpenEx();

       if (openEx) {

           int i = 1 / 0;

       }


       // 修改订单【已支付】

       boolean result = this.update(new LambdaUpdateWrapper()

               .eq(OmsOrder::getId, orderId)

               .set(OmsOrder::getStatus, OrderStatusEnum.WAIT_SHIPPING.getValue())

       );


       return result;

   }


会员服务

按照 【第三节-Seata客户端搭建 】 在 mall-ums 模块添加 Maven 依赖和客户端的配置,在 mall-ums 数据库创建 undo_log 表。


扣减余额关键代码:


   @ApiOperation(value = "「实验室」扣减会员余额")

   @PutMapping("/{memberId}/balances/_deduct")

   public Result deductBalance(@PathVariable Long memberId, @RequestParam Long amount) {

       boolean result = memberService.update(new LambdaUpdateWrapper()

               .setSql("balance = balance - " + amount)

               .eq(UmsMember::getId, memberId));

       return Result.judge(result);

   }


测试

以上就基于 youlai-mall 商城订单支付的业务简单实现的 Seata 实验室,接下来通过测试来看看 Seata 分布式事务的能力。


未开启事务

未开启事务前提: 订单状态因为异常修改失败,但这并未影响到商品库存扣减和余额扣减成功的结果,明显这不是希望的结果。

微信图片_20230710090946.png



开启事务

开启事务前提:订单状态修改发生异常,同时也回滚了扣减库存、扣减余额的行为,可见 Seata 分布式事务生效。

/微信图片_20230710090949.png



六. Seata 源码

因为 Seata 源码牵涉角色比较多,需要在本地搭建 seata-server 然后和 Seata 客户端交互调试,后面整理出来会单独拿一篇文章进行进行具体分析。

微信图片_20230710091009.png



七. 结语

本篇通过 Seata 1.5.2 版本部署到实战讲述了 Seata 分布式事务AT模式在商城订单支付业务场景的应用,相信大家对 Seata 和有来实验室有个初步的认知,但这里还只是一个开始,后续会有更多的热门中间件登上实验室舞台。当然,可见这个舞台很大,所以也希望有兴趣或者有想法同学加入有来实验室的开发。


附. 源码

本文源码已推送至gitee和github仓库


gitee github

后端工程 youlai-mall youlai-mall

前端工程 mall-admin mall-admin


相关文章
|
8月前
|
IDE Java Linux
Seata常见问题之重新打包以单独用jar来部署如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
277 1
|
8月前
|
SQL Oracle 关系型数据库
seata版本问题之码云拉取代码异常如何解决
Seata是一款开源的分布式事务解决方案,旨在提供高效且无缝的分布式事务服务;在集成和使用Seata过程中,开发者可能会遇到不同的异常问题,本合集针对Seata常见异常进行系统整理,为开发者提供详细的问题分析和解决方案,助力高效解决分布式事务中的难题。
285 6
|
8月前
|
关系型数据库 Linux Nacos
Linux 环境下使用 Docker 部署 Seata 1.7.1 (图文教程)
Linux 环境下使用 Docker 部署 Seata 1.7.1 (图文教程)
|
8月前
|
存储 Java Nacos
Seata常见问题之springboot 2.3.7 和高版本 seata 2.0.0,1.6.1不兼容如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
935 0
|
8月前
|
关系型数据库 Java Nacos
Seata的部署和集成
部署Seata的tc-server
|
3月前
|
前端开发 Java API
Apache Seata(incubating) 首个版本重磅发布!
2.1.0 是 Seata 进入 Apache 基金会的第一个 Release Version。此次发布将 io.seata 包名更改为 org.apache.seata。除了按原有的 Roadmap 技术演进外,2.1.0 进行了大量兼容性工作,实现了 API、数据和协议的兼容。用户无需修改原有的 API 和配置,即可实现到 Apache 版本的平滑升级。
128 18
Apache Seata(incubating) 首个版本重磅发布!
|
5月前
|
Java Nacos Docker
"揭秘!Docker部署Seata遇上Nacos,注册成功却报错?这些坑你不得不防!一网打尽解决秘籍,让你的分布式事务稳如老狗!"
【8月更文挑战第15天】在微服务架构中,Nacos搭配Seata确保数据一致性时,Docker部署Seata后可能出现客户端连接错误,如“can not connect to services-server”。此问题多由网络配置不当、配置文件错误或版本不兼容引起。解决策略包括:调整Docker网络设置确保可达性;检查并修正`file.conf`和`registry.conf`中的Nacos地址和端口;验证Seata与Nacos版本兼容性;修改配置后重启服务;参考官方文档和最佳实践进行配置。通过这些步骤,能有效排除故障,保障服务稳定运行。
383 0
|
8月前
|
Kubernetes Cloud Native API
欢迎报名 Apache Seata (incubating) 开源之夏
Apache Seata (incubating) 邀请学生参加 2024 年开源之夏活动,报名时间为 4 月 30 日至 6 月 3 日。该项目旨在培养分布式事务领域的开发者,参与者将远程协作并有机会获得奖金。
1339 20
|
8月前
|
Java 数据库连接 API
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
148 0
|
8月前
|
开发框架 Java 数据库连接
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)(下)
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
116 0