微服务事务管理(Dubbo)

Seata 是什么

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

一、示例架构说明

可在此查看本示例完整代码地址:dubbo-samples-seata

用户采购商品业务,整个业务包含3个微服务:

  • 库存服务: 扣减给定商品的库存数量。
  • 订单服务: 根据采购请求生成订单。
  • 账户服务: 用户账户金额扣减。

image.png

StorageService

public interface StorageService {/*** 扣除存储数量*/void deduct(String commodityCode, int count);
}

OrderService

public interface OrderService {/*** 创建订单*/Order create(String userId, String commodityCode, int orderCount);
}

AccountService

public interface AccountService {/*** 从用户账户中借出*/void debit(String userId, int money);
}

二、主要的业务逻辑

BusinessService

public class BusinessServiceImpl implements BusinessService {private StorageService storageService;private OrderService orderService;/*** 采购*/public void purchase(String userId, String commodityCode, int orderCount) {// 扣除存储数量storageService.deduct(commodityCode, orderCount);// 创建订单orderService.create(userId, commodityCode, orderCount);}
}

StorageService

public class StorageServiceImpl implements StorageService {private JdbcTemplate jdbcTemplate;@Overridepublic void deduct(String commodityCode, int count) {// 修改数据库:扣减存储数量jdbcTemplate.update("update storage_tbl set count = count - ? where commodity_code = ?",new Object[]{count, commodityCode});}
}

OrderService

public class OrderServiceImpl implements OrderService {private AccountService accountService;private JdbcTemplate jdbcTemplate;public Order create(String userId, String commodityCode, int orderCount) {// 计算金额int orderMoney = calculate(commodityCode, orderCount);// 用户账户中扣减金额accountService.debit(userId, orderMoney);// 修改数据库:新建订单final Order order = new Order();order.userId = userId;order.commodityCode = commodityCode;order.count = orderCount;order.money = orderMoney;KeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(con -> {PreparedStatement pst = con.prepareStatement("insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)",PreparedStatement.RETURN_GENERATED_KEYS);pst.setObject(1, order.userId);pst.setObject(2, order.commodityCode);pst.setObject(3, order.count);pst.setObject(4, order.money);return pst;}, keyHolder);order.id = keyHolder.getKey().longValue();return order;}
}

AccountService

public class AccountServiceImpl implements AccountService {private JdbcTemplate jdbcTemplate;@Overridepublic void debit(String userId, int money) {  // 修改数据库:用户账户中扣减金额      jdbcTemplate.update("update account_tbl set money = money - ? where user_id = ?", new Object[]{money, userId});}
}

三、快速启动示例

Step 1: 下载源码

git clone -b master https://github.com/apache/dubbo-samples.git
cd ./dubbo-samples-transaction/

Step 2: 通过 docker-compose 启动 Seata-Server 和 MySQL 等

在此示例中,我们使用 docker-compose 快速拉起 seata-server 和 mysql 等服务。

cd src/main/resources/docker
docker-compose up

Step 3: 构建用例

执行 maven 命令,打包 demo 工程

mvn clean package

Step 4: 启动 AccountService

java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboAccountServiceStarter

Step 5: 启动 OrderService

java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboOrderServiceStarter

Step 6: 启动 StorageService

java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboStorageServiceStarter

Step 7: 启动 BusinessService

java -classpath ./target/dubbo-samples-transaction-1.0-SNAPSHOT.jar org.apache.dubbo.samples.starter.DubboBusinessTester

四、示例核心流程

 

image.png

Step 1: 修改业务代码

此处仅仅需要一行注解 @GlobalTransactional 写在业务发起方的方法上:

    @GlobalTransactionalpublic void purchase(String userId, String commodityCode, int orderCount) {......}

Step 2: 安装数据库

  • 要求: MySQL (InnoDB 存储引擎)。

提示: 事实上例子中3个微服务需要3个独立的数据库,但为了方便我们使用同一物理库并配置3个逻辑连接串。

更改以下xml文件中的数据库url、username和password

dubbo-account-service.xml dubbo-order-service.xml dubbo-storage-service.xml

    <property name="url" value="jdbc:mysql://x.x.x.x:3306/xxx" /><property name="username" value="xxx" /><property name="password" value="xxx" />

Step 3: 为 Seata 创建 undo_log 表

UNDO_LOG 此表用于 Seata 的AT模式。

-- 注意当 Seata 版本升级至 0.3.0+ 将由之前的普通索引变更为唯一索引。
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;

Step 4: 创建相关业务表


DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`commodity_code` varchar(255) DEFAULT NULL,`count` int(11) DEFAULT 0,PRIMARY KEY (`id`),UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) DEFAULT NULL,`commodity_code` varchar(255) DEFAULT NULL,`count` int(11) DEFAULT 0,`money` int(11) DEFAULT 0,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) DEFAULT NULL,`money` int(11) DEFAULT 0,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Step 5: 启动 Seata-Server 服务

  • 下载服务器软件包,将其解压缩。
Usage: sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows) [options]Options:--host, -hThe host to bind.Default: 0.0.0.0--port, -pThe port to listen.Default: 8091--storeMode, -mlog store mode : file、dbDefault: file--helpe.g.sh seata-server.sh -p 8091 -h 127.0.0.1 -m file

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/60969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第八周第四天学习总结

测试linux基础并复习基础命令

系统架构设计高级技能 · Web架构

现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 点击进入系列文章目录 系统架构设计高级技能 Web架构 一、Web架构介绍1.1 Web架构涉及技术1.2 单台服务…

springCloud整合Zookeeper的时候调用找不到服务

SpringCloud整合Zookeeper的时候调用找不到服务 首先&#xff0c;我们在注册中心注册了这个服务&#xff1a; 然后我们使用RestTemplate 调用的时候发现失败了&#xff1a;找不到这个服务&#xff1a; 找了很多资料发现这个必须要加上负载才行 BeanLoadBalanced //负载publi…

iOS开发Swift-闭包

1.闭包表达式语法 { (参数) -> return 类型 in//内容 }let names ["C", "A", "E", "B", "D"] func back(_ s1: String, s2: String) -> Bool {return s1 > s2 //(B > A, C > B) }//闭包后&#xff1a; va…

在CentOS7中,安装并配置Redis【个人笔记】

一、拓展——Ubuntu上安装Redis 输入命令su --->切换到root用户【如果已经是&#xff0c;则不需要进行该操作】apt search redis --->使用apt命令来搜索redis相关的软件包【查询后&#xff0c;检查redis版本是否是你需要的&#xff0c;如果不是则需要看看其他资料~】ap…

面试总结 - 计算机网络

计算机网络 1 OSI 七层模型 | TCP与UDP | 响应状态码 OSI 模型 应用层: 计算机用户&#xff0c;以及各种应用程序和网络之间的接口&#xff0c;其功能是直接向用户提供服务&#xff0c;完成用户希望在网络上完成的各种工作。 HTTP SMTP FTP DNS 表示层: 负责数据格式的转换&…

银河麒麟V10(Tercel)服务器版安装 Docker

一、服务器环境 ## 查看系统版本&#xff0c;确认版本 cat /etc/kylin-release Kylin Linux Advanced Server release V10 (Tercel)## 操作系统 uname -p aarch64## 内核版本&#xff08;≥ 3.10&#xff09; uname -r 4.19.90-21.2.ky10.aarch64## iptables 版本&#xff08;…

Windows系统下MMDeploy预编译包的使用

Windows系统下MMDeploy预编译包的使用 MMDeploy步入v1版本后安装/使用难度大幅下降&#xff0c;这里以部署MMDetection项目的Faster R-CNN模型为例&#xff0c;将PyTorch模型转换为ONNX进而转换为Engine模型&#xff0c;部署到TensorRT后端&#xff0c;实现高效推理&#xff0c…

笔试题-计算公式优先级+运算符运算+运算符执行

package com.xch.test04;/*** 笔试题测试** author XuChenghe* date 2023/8/31 16:03*/ public class Test08 {public static void main(String[] args) {f1();System.out.println();f2();System.out.println();f3();}/*** 计算公式优先级*/public static void f1() {int x 10…

ASP.NET Core 的错误页面

异常处理 Developer 环境的异常页面 ASP.NET Core App 会可以在开发阶段用UseDeveloperExceptionPage启用 Developer 异常页面&#xff1a; app.UseDeveloperExceptionPage();当遇到Unhandled 异常信息时&#xff0c;可以输出异常信息页面&#xff1a; 异常信息包括&#xf…

算法第一天——数组理论基础

数组 数组是存放连续内存空间上的相同类型数据的集合&#xff0c; 数组的下标都是从0开始&#xff0c; 数组内存空间的地址是连续的。 数组元素不能删除&#xff0c;只能修改。即数组数组一旦分配了内存空间就不能修改空间大小。 但是在java中&#xff0c;java的内存的空间地址…

Django学习笔记-实现联机对战

笔记内容转载自 AcWing 的 Django 框架课讲义&#xff0c;课程链接&#xff1a;AcWing Django 框架课。 CONTENTS 1. 统一长度单位2. 增加联机对战模式3. 配置Django Channels 1. 统一长度单位 多人模式中每个玩家所看到的地图相对来说应该是一样的&#xff0c;因此需要固定地…

30 - 个人博客项目-01-配置环境

(1). 安装第三方库 pip install flask2.3.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip3 install jinja23.1.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install flask-script2.0.5 -i h…

《Kubernets证书篇:kubernetes1.24.17证书修改时间限制》

一、背景 Kubernetes 默认的证书有效期只有1年,因此需要每年手动更新一次节点上面的证书,特别麻烦而且更新过程中可能会出现问题,因此我们要对 Kubernetes 的 SSL 证书有效期进行修改,这里将证书的时间限制修改为100年。 环境信息如下: 操作系统内核版本K8S版本Ubuntu 20.…

含纽扣电池的产品出口澳洲需要做哪些认证?认证标准是什么?

澳大利亚含纽扣电池产品新规 01纽扣电池安全问题<<<< 在澳大利亚&#xff0c;已有儿童因为误食纽扣电池而导致死亡&#xff0c;且每月至少有一名儿童因吞咽或插入纽扣/硬币电池而严重受伤&#xff0c;导致其中一些儿童永久性损伤&#xff0c;而全世界数以百万计的…

5分钟快速搭建!这款颜值爆表的数据可视化工具,你值得拥有!

最好的数据可视化工具是什么&#xff1f; 没有最好&#xff0c;只有最适合的。不过&#xff0c;想要找一个优秀的数据可视化工具&#xff0c;可以从下面几点进行评估&#xff1a; &#xff08;1&#xff09;易用性&#xff1a; 直观的界面可以帮助新手快速上手&#xff0c;并…

kafka--技术文档--架构体系

架构体系 Kafka的架构体系包括以下几个部分&#xff1a; Producer. 消息生产者&#xff0c;就是向Kafka broker发送消息的客户端。Broker. 一台Kafka服务器就是一个Broker。一个集群由多个Broker组成。一个Broker可以容纳多个Topic。Topic. 可以理解为一个队列&#xff0c;一…

200. 岛屿数量

200. 岛屿数量 class Solution { public:vector<vector<char>> g;int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, -1};int numIslands(vector<vector<char>>& grid) {g grid;int cnt 0;for (int i 0; i < g.size(); i )for (int j 0; j <…

JVM垃圾回收算法和CMS垃圾收集器

目录 判断一个对象是否死亡&#xff1f; 1、引用计数法 2、可达性分析算法 三色标记 垃圾收集算法 1、分代收集理论 2、垃圾回收算法 标记-清除 标记-复制 标记-整理 CMS&#xff08;Concurrent Mark Sweep&#xff09;收集器 CMS垃圾收集器步骤 CMS垃圾收集器优…