Seata概念以及简单应用

Seata是一款开源的分布式事务解决方案,用于处理微服务架构中的分布式事务。本文介绍了分布式事务问题的由来,Seata的概念以及其组件模型。详细讲解了Seata Server的安装、配置和使用,包括修改配置文件、数据库存储设置和启动过程。同时,通过实例展示了Seata如何在订单服务、库存服务和账户服务之间协调分布式事务,确保数据一致性。在Seata@GlobalTransactional的验证中,证明了其在异常情况下能有效回滚事务,避免错误数据入库。
摘要由CSDN通过智能技术生成


参考尚硅谷

SpringCloud Alibaba Seata处理分布式事务

1.分布式事务问题由来

我们之前都是一个应用程序连一个库,而且应用程序和数据库被放在同一台机器上,但是在分布式微服务的系统架构中,将原来的三个模块拆分成三个独立的应用,分别使用三个独立的数据源。如下图所示

在这里插入图片描述

1.仓储服务:对给定商品扣除仓储数量。

2.订单服务:根据采购需求创建订单。

3.账户服务:从用户账户中扣除余额。

上述操作都需要操作相应的数据库,但是如何保证数据库的全局一致性是一个很大的问题。一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。

2.什么是Seata?

Seata是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

3.分布式事务的相关概念

分布式事务处理过程的一ID+三组件模型,一ID即Transaction ID XID,全局唯一的事务ID。

三组件:

1.TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

2.TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

3.RM (Resource Manager) - 资源管理器

管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

然后我们看一下Seata处理流程

在这里插入图片描述

如图所示一个TC管理全局,一个XID带着TC,TM,RM。

1.TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID。

2.XID在微服务调用链路的上下文中传播。

3.RM向TC注册分支事务,将其纳入XID对应的全局事务的管辖。

4.TM向TC发起针对XID的全局提交或回滚决议。

5.TC调度XID下管辖的全部分支事务完成提交或者回滚请求。

4.Seata Server的安装和使用

下载地址Tags · seata/seata (github.com)

4.1 Seata修改配置文件

下载之后解压到自己的目录下,然后修改file.conf文件

在这里插入图片描述

修改service模块的group自己随便写一个。

在这里插入图片描述

然后修改store模块,他之前是mode是file文件存储,我们把他改成数据库存储。

在这里插入图片描述

然后是修改db模块将他的数据库配置改成你自己的主要是账号密码。然后就是建表这个不用你自己写人家给你写好了。

在这里插入图片描述

然后你复制粘贴里面的内容放到你自己的数据库下面执行就行了。

然后你再找到解压文件夹里面的registry.conf修改注册信息

在这里插入图片描述

4.2seata的启动

因为上面配置文件说这个东西得注册到nacos里面所以要想启动seata必须先启动nacos否则会报错。

启动成功后应该是这样的

在这里插入图片描述

在这里插入图片描述

5.Seata实例

5.1业务声明

这里我们创建三个服务,一个订单服务,一个库存服务,一个账户服务。当用户下单时,会在订单服务中创建一个订单,然后通过远程调用库存服务来扣减下单商品的库存,再通过远程调用账户服务来扣减用户账户里面的余额,最后在订单服务中修改订单状态为已完成。该操作跨越三个数据库,有两次远程调用,很明显会有分布式事务问题。

5.2数据库准备

首先我们创建数据库

create database seata_order;
create database seata_storage;
create database seata_account;

然后分别在对应的库下面建立相应的表

USE
seata_order;
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order`
(
    `int`        bigint(11) NOT NULL AUTO_INCREMENT,
    `user_id`    bigint(20) DEFAULT NULL COMMENT '用户id',
    `product_id` bigint(11) DEFAULT NULL COMMENT '产品id',
    `count`      int(11) DEFAULT NULL COMMENT '数量',
    `money`      decimal(11, 0) DEFAULT NULL COMMENT '金额',
    `status`     int(1) DEFAULT NULL COMMENT '订单状态:  0:创建中 1:已完结',
    PRIMARY KEY (`int`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
USE
seata_storage;
DROP TABLE IF EXISTS `t_storage`;
CREATE TABLE `t_storage`
(
    `int`        bigint(11) NOT NULL AUTO_INCREMENT,
    `product_id` bigint(11) DEFAULT NULL COMMENT '产品id',
    `total`      int(11) DEFAULT NULL COMMENT '总库存',
    `used`       int(11) DEFAULT NULL COMMENT '已用库存',
    `residue`    int(11) DEFAULT NULL COMMENT '剩余库存',
    PRIMARY KEY (`int`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '库存' ROW_FORMAT = Dynamic;
INSERT INTO `t_storage`
VALUES (1, 1, 100, 0, 100);

USE
seata_account;
DROP TABLE IF EXISTS `t_account`;
CREATE TABLE `t_account`
(
    `id`      bigint(11) NOT NULL COMMENT 'id',
    `user_id` bigint(11) DEFAULT NULL COMMENT '用户id',
    `total`   decimal(10, 0) DEFAULT NULL COMMENT '总额度',
    `used`    decimal(10, 0) DEFAULT NULL COMMENT '已用余额',
    `residue` decimal(10, 0) DEFAULT NULL COMMENT '剩余可用额度',
    PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '账户表' ROW_FORMAT = Dynamic;
INSERT INTO `t_account`
VALUES (1, 1, 1000, 0, 1000);

然后分别建立相应的回滚日志

DROP TABLE IF EXISTS `undo_log`;
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;

最后数据库结构应该是这样的
在这里插入图片描述

5.3业务逻辑编写

5.3.1 seata-order-service

新建一个module端口号为2001。

pom.xml

<dependencies>
        <!-- nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- seata -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>seata-all</artifactId>
                    <groupId>io.seata</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId
评论 64
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温JZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值