SpringCloud - Seata 分布式事务
前言
该博客为Sentinel学习笔记,主要目的是为了帮助后期快速复习使用
学习视频:7小快速通关SpringCloud
辅助文档:SpringCloud快速通关
源码地址:cloud-demo
一、简介
官网:https://seata.apache.org/zh-cn/
Seata 是一款开源的分布式事务解决方案,旨在解决微服务架构中跨服务的事务一致性问题。它支持多种事务模型(如AT、TCC、SAGA),能够保证跨多个服务和数据库的数据一致性,简化了分布式事务的管理。

为什么需要使用 Seata?
在分布式系统中,由于涉及多个微服务和多个数据库,事务的一致性和可靠性成为了一个挑战。传统的事务管理机制(如两阶段提交)不适用于复杂的微服务环境,因为它们的成本高、实现复杂且不易扩展。
Seata 的优势体现在以下几个方面:
- 分布式事务支持:
Seata提供了跨多个服务和数据库的事务支持,确保多个服务的操作能够像一个单一事务一样进行提交或回滚。 - 性能优化:
Seata采用高效的事务协调机制,通过减少分布式事务处理的开销,显著提升系统性能。 - 可靠性和容错性:
Seata的设计保证了事务的一致性和可靠性,即使在部分节点发生故障时,也能保证系统的正确性。 - 简化开发:使用
Seata时,开发者不需要自己编写复杂的分布式事务处理逻辑,Seata 提供了易用的注解和API,极大地简化了开发工作。 - 灵活的事务模型:
Seata提供了多种事务模型(AT、TCC、SAGA),可以根据具体业务场景选择合适的事务管理方式,满足不同的需求。

二、快速入门
2.1 环境准备

2.2 原理

2.2.1 核心组件
Seata分布式事务的工作原理主要涉及三个核心组件:事务协调器(TC)、事务管理器(TM)和资源管理器(RM)。以下是这些组件的详细工作原理:
- 事务协调器(TC):
TC负责维护全局事务的状态,并协调事务的提交或回滚。 它接收全局事务的开始、提交或回滚请求,协调各个服务的事务执行。TC在收到所有分支事务的提交或回滚确认后,将全局事务状态标记为结束。 - 事务管理器(TM):
TM负责定义和发起全局事务。 当TM发起一个全局事务时,TC创建一个全局事务ID,并将该事务状态设置为“开始”状态。TM通知TC提交事务,TC依次通知各RM提交其分支事务。如果任一分支事务执行失败或出现异常,TM通知TC回滚事务,TC会依次通知各RM进行回滚操作。 - 资源管理器(RM):
RM负责管理分支事务(Branch Transaction),并与本地数据库资源交互,确保各个分支事务的提交和回滚操作。 在全局事务的生命周期内,多个服务会分别执行属于自己的本地事务(即分支事务)。每个分支事务在执行前需要向TC注册,并绑定到全局事务ID上。每个服务的RM负责管理分支事务的执行,并与本地资源交互。执行完成后,RM会向TC报告分支事务的执行结果。
2.2.1 实现步骤
Seata的分布式事务管理通过以下步骤实现:
- 全局事务开始:当TM发起一个全局事务时,TC创建一个全局事务ID,并将该事务状态设置为“开始”状态。
- 注册分支事务:在全局事务的生命周期内,多个服务会分别执行属于自己的本地事务(即分支事务)。每个分支事务在执行前需要向TC注册,并绑定到全局事务ID上。
- 分支事务执行:每个服务的RM负责管理分支事务的执行,并与本地资源交互。执行完成后,RM会向TC报告分支事务的执行结果。
- 全局提交或回滚:当所有分支事务都执行成功时,TM通知TC提交事务,TC依次通知各RM提交其分支事务。如果任一分支事务执行失败或出现异常,TM通知TC回滚事务,TC会依次通知各RM进行回滚操作。
- 事务结束:TC在收到所有分支事务的提交或回滚确认后,将全局事务状态标记为结束。
2.3 seata-server
- 下载:https://seata.apache.org/zh-cn/download/seata-server
- 解压并启动:
seata-server.bat


Server端口【TC事务协调者】:8091
Web可视化界面:http://localhost:7091,账号和密码都为seata


2.4 微服务配置
2.4.1 引依赖
<!-- 分布式事务Seata --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>
2.4.2 配置
每个微服务创建 file.conf文件,完整内容如下;
【微服务只需要复制 service 块配置即可】
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#transport {# tcp, unix-domain-sockettype = "TCP"#NIO, NATIVEserver = "NIO"#enable heartbeatheartbeat = true# the tm client batch send request enableenableTmClientBatchSendRequest = false# the rm client batch send request enableenableRmClientBatchSendRequest = true# the rm client rpc request timeoutrpcRmRequestTimeout = 2000# the tm client rpc request timeoutrpcTmRequestTimeout = 30000# the rm client rpc request timeoutrpcRmRequestTimeout = 15000#thread factory for nettythreadFactory {bossThreadPrefix = "NettyBoss"workerThreadPrefix = "NettyServerNIOWorker"serverExecutorThread-prefix = "NettyServerBizHandler"shareBossWorker = falseclientSelectorThreadPrefix = "NettyClientSelector"clientSelectorThreadSize = 1clientWorkerThreadPrefix = "NettyClientWorkerThread"# netty boss thread sizebossThreadSize = 1#auto default pin or 8workerThreadSize = "default"}shutdown {# when destroy server, wait secondswait = 3}serialization = "seata"compressor = "none"
}
service {#transaction service group mappingvgroupMapping.default_tx_group = "default"#only support when registry.type=file, please don't set multiple addressesdefault.grouplist = "127.0.0.1:8091"#degrade, current not supportenableDegrade = false#disable seatadisableGlobalTransaction = false
}client {rm {asyncCommitBufferLimit = 10000lock {retryInterval = 10retryTimes = 30retryPolicyBranchRollbackOnConflict = true}reportRetryCount = 5tableMetaCheckEnable = falsetableMetaCheckerInterval = 60000reportSuccessEnable = falsesagaBranchRegisterEnable = falsesagaJsonParser = "fastjson"sagaRetryPersistModeUpdate = falsesagaCompensatePersistModeUpdate = falsetccActionInterceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000sqlParserType = "druid"branchExecutionTimeoutXA = 60000connectionTwoPhaseHoldTimeoutXA = 10000}tm {commitRetryCount = 5rollbackRetryCount = 5defaultGlobalTransactionTimeout = 60000degradeCheck = falsedegradeCheckPeriod = 2000degradeCheckAllowTimes = 10interceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000}undo {dataValidation = trueonlyCareUpdateColumns = truelogSerialization = "jackson"logTable = "undo_log"compress {enable = true# allow zip, gzip, deflater, lz4, bzip2, zstd default is ziptype = zip# if rollback info size > threshold, then will be compress# allow k m g tthreshold = 64k}}loadBalance {type = "XID"virtualNodes = 10}
}
log {exceptionRate = 100
}
tcc {fence {# tcc fence log table namelogTableName = tcc_fence_log# tcc fence log clean periodcleanPeriod = 1h}
}
2.4.3 开启全局事务
在最大的方法入口,标记@GlobalTransactional,即可开启全局事务
2.5 二阶提交协议原理
第一阶段:本地事务
- 全局事务开始:业务层发起全局事务请求,事务协调者(
TC)注册全局事务并生成全局事务ID。 - 分支事务注册:各个分支事务(如扣减库存、创建订单、扣减余额)分别向
TC注册,申请必要的资源锁(如数据库表的记录锁)。 - 执行本地事务:
- 扣减库存:扣减库存:执行SQL
update storage_tbl set count = count - 2 where commodity_code = 'P0001',更新库存数量。 - 创建订单:执行订单创建相关的本地事务。
- 扣减余额:执行扣减账户余额的本地事务。
- 扣减库存:扣减库存:执行SQL
- 记录前后镜像:在执行业务SQL前后,分别查询并记录数据的前后镜像,用于生成回滚日志(
UNDO LOG)。 - 插入回滚日志:将前后镜像组成的回滚日志插入到
UNDO LOG表中,以便在需要时进行数据回滚。 - 本地事务提交:将业务数据和
UNDO LOG一起保存,并汇报自己提交成功与否的结果。
第二阶段:提交阶段
- 分支提交:
- 收到
TC的提交请求后,各个分支事务立即响应OK,表示准备就绪。 - 给异步任务队列中添加异步任务,异步和批量地删除相应的
UNDO LOG记录。
- 收到
- 分支回滚:
- 如果TC的提交请求未能成功,或者在第一阶段中某个分支事务失败,
TC将发起回滚请求。 - 各个分支事务收到回滚请求后,开启一个本地事务,执行以下任务:
- 找到对应的UNDO LOG记录。
- 数据校验:比较后镜像与当前数据,如果不一致,则说明数据被其他渠道修改,需要进行相应处理;如果一致,则执行回滚。
- 回滚数据:根据
UNDO LOG的前镜像内容执行数据修改,完成后删除UNDO LOG。
- 如果TC的提交请求未能成功,或者在第一阶段中某个分支事务失败,
通过以上流程,Seata确保了分布式事务的原子性,即所有分支事务要么全部成功提交,要么全部回滚,从而保证了数据的一致性。

2.6 二阶提交协议可视化
2.6.1 观察初始数据库

2.6.2 设置断点
我们在业务服务BusinessServiceImpl的主方法purchase中给远程调用方法deduct和create加上断点

并在订单服务OrderServiceImpl的create方法中添加一个除零异常,并在前面加上一个断点

2.6.3 发起请求,观察数据变化
在浏览器发送请求,http://localhost:11000/purchase?userId=1&commodityCode=P0001&count=2
这里,我们来到第一个断点扣减库存deduct,可以看到控制台打印开启了一个新的全局事务

此时在Seata控制台中可以观测到这个全局事务
当前没有任何数据提交,即没有全局锁 -> 只有第一阶段本地提交,要修改数据之前,才会申请自己数据的记录锁,即全局锁

继续放行到第二个断点位置,创建订单create,观察Seata控制台,开启分支事务并查看
可以看到storage_db的分支事务

而且在全局锁中也可以看到数据 -> 分支事务一定会提交一个数据

继续观察storage_db数据库,可以看到库存已经被扣减,并且在undo_log表中有一条记录


查看rollback_info字段的内容,
在前镜像" beforeImage "中可以看到,在记录修改之前的值为100 "value": 100
后镜像"afterImage",扣减库存后的数据为,"value": 98
{"@class": "org.apache.seata.rm.datasource.undo.BranchUndoLog","xid": "192.168.4.105:8091:7782838703486791689","branchId": 7782838703486791690,"sqlUndoLogs": ["java.util.ArrayList",[{"@class": "org.apache.seata.rm.datasource.undo.SQLUndoLog","sqlType": "UPDATE","tableName": "storage_tbl","beforeImage": {"@class": "org.apache.seata.rm.datasource.sql.struct.TableRecords","tableName": "storage_tbl","rows": ["java.util.ArrayList",[{"@class": "org.apache.seata.rm.datasource.sql.struct.Row","fields": ["java.util.ArrayList",[{"@class": "org.apache.seata.rm.datasource.sql.struct.Field","name": "count","keyType": "NULL","type": 4,"value": 100},{"@class": "org.apache.seata.rm.datasource.sql.struct.Field","name": "id","keyType": "PRIMARY_KEY","type": 4,"value": 1}]}}]]},"afterImage": {"@class": "org.apache.seata.rm.datasource.sql.struct.TableRecords","tableName": "storage_tbl","rows": ["java.util.ArrayList",[{"@class": "org.apache.seata.rm.datasource.sql.struct.Row","fields": ["java.util.ArrayList",[{"@class": "org.apache.seata.rm.datasource.sql.struct.Field","name": "count","keyType": "NULL","type": 4,"value": 98},{"@class": "org.apache.seata.rm.datasource.sql.struct.Field","name": "id","keyType": "PRIMARY_KEY","type": 4,"value": 1}]}}]]}}]]
}
继续放行到第三个断点位置,保存订单orderTblMapper.insert(orderTbl);,观察Seata控制台
可以看到多了account_db的分支事务和全局锁


此时数据库的余额和库存均被扣减,并且生成了UNDO LOG记录

此时继续放行,即会执行int i = 1/0;抛出除零异常,所有数据全部按照前镜像回滚,UNDO LOG记录

注意:事务事务超时时间为一分钟,调试过程中,一旦超时会报一下错误
may be has finished->事务可能完成
branch register failed->分支注册事务失败
2025-02-13T22:41:16.010+08:00 ERROR 19556 --- [seata-storage] [io-13000-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.transaction.TransactionSystemException: JDBC commit failed] with root causeorg.apache.seata.core.exception.RmTransactionException: branch register failed, xid: 192.168.4.105:8091:7782838703486791747, errMsg: TransactionException[Could not found global transaction xid = 192.168.4.105:8091:7782838703486791747, may be has finished.]
2.7 四种事务模式
2.7.1 AT模式
这是Seata中最常用的一种分布式事务模式,它通过自动的预提交、回滚操作,实现分布式事务的透明化管理。AT模式的核心在于自动处理数据库的事务操作,不需要对业务代码进行侵入性的修改。
2.7.2 TCC模式
适用于需要显式控制分布式事务的场景,确保所有参与者都遵循统一的规则。TCC模式通过三阶段的提交(Try、Confirm、Cancel)来保证最终一致性。适用于夹杂非数据库操作的事务。
2.7.3 Saga模式
适用于复杂的业务流程,每个步骤都可以独立地进行业务逻辑处理。在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
2.7.4 XA模式
适用于需要兼容传统数据库系统的场景,支持多种资源管理器。XA模式是强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入。
2.7.5 切换模式
添加application.yml配置
seata:data-source-proxy-mode: AT #默认为AT模式
相关文章:
SpringCloud - Seata 分布式事务
前言 该博客为Sentinel学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 源码地址:cloud-demo 一、简介 官网:https://seata.apache.org/zh-cn/ Seata …...
Ansible批量配置服务器免密登录步骤详解
一、准备工作 192.168.85.138 安装ansible,计划配置到139的免密 192.168.85.139 待配置免密 1. 生成SSH密钥对 在Ansible控制节点生成密钥对,用于后续免密认证: ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa 全部回车默认,无…...
互联网大厂中面试的高频计算机网络问题及详解
前言 哈喽各位小伙伴们,本期小梁给大家带来了互联网大厂中计算机网络部分的高频面试题,本文会以通俗易懂的语言以及图解形式描述,希望能给大家的面试带来一点帮助,祝大家offer拿到手软!!! 话不多说,我们立刻进入本期正题! 一、计算机网络基础部分 1 …...
人工智能时代下ai智能语音机器人如何以假乱真?
智能语音机器人若要达到以假乱真的效果,需要在以下几个关键方面不断提升: 一、语音合成技术 音色模拟 多维度采样 对大量真人语音样本进行多维度采样,包括不同年龄、性别、地域的人的语音。例如,采集不同年龄段男性从低沉到清亮…...
【橘子ES】Aggregations 聚合准备
一、聚合的概念 聚合文档 聚合区别于检索,检索是使用一系列条件把文档从es中搜索回来。但是聚合则是在搜索回来的文档的基础上进一步进行处理。 简单来说聚合就是将数据汇总为指标、统计数据或其他分析。聚合可以解决以下几类问题: 我的网站的平均加载…...
vue3读取webrtc-stream 视频流
一.首先下载webrtc-stream,方便自己本地搭建视频流服务 https://download.csdn.net/download/cyw8998/90373521 解压后,启动命令 webrtc-streamer.exe -H 127.0.0.1:8020 二.vue3代码如下 <template><h1>video</h1><video id&…...
springcloud集成gateway
本篇文章只介绍gateway模块的搭建步骤,并无gateway详细介绍 gateway详解请查看:SpringCloudGateway官方文档详解 前置处理 父模块中已指定版本 不知道如何选择版本看这篇: 手把手教你梳理springcloud与springboot与springcloudalibaba的版本…...
2025常用的SEO工具有哪些?
在互联网时代,如何让自己的网站或内容脱颖而出,成为许多企业和个人站长们最关注的问题。而在这个过程中,SEO(搜索引擎优化)作为一种有效的提升网站曝光度和吸引流量的手段,已经成为了网站运营的核心之一。对…...
C++类和对象进阶:运算符重载深度详解
C类和对象进阶:运算符重载 前言引入运算符重载定义语法注意事项重载为全局函数重载为成员函数运算符重载的本质 默认赋值运算符重载(默认成员函数)编译器自己生成的赋值运算符重载函数需要自己实现的场景总结默认赋值运算符重载 拷贝构造函数和赋值重载的区分验证 总…...
Mybatisplus——Mybatisplus3.5.2版本使用Page分页插件查询,records有数据但是total显示0
目录 一、问题背景 debug 执行Mybatisplus使用Page分页插件查询时,发现 Page 里面的records有数据但是total显示0。 二、问题产生的原因 未配置MybatisPlus的分页插件拦截器导致的或者因mybatis-plus版本3.4或3.5版本导致原先的分页插件paginationInterceptor无法…...
C#(Winform)通过添加AForge添加并使用系统摄像机
先展示效果 AForge介绍 AForge是一个专门为开发者和研究者基于C#框架设计的, 也是NET平台下的开源计算机视觉和人工智能库 它提供了许多常用的图像处理和视频处理算法、机器学习和神经网络模型,并且具有高效、易用、稳定等特点。 AForge主要包括: 计算机视觉与人…...
AI使用场景简单测试
前言 今天来分享下AI的2个实用场景,我这里是使用的博主:小虚竹,搭建的AI服务,用的ChatGPT 4O模型,主要是试了3个场景,服装设计、直播带货话术、检验报告分析。 一、服装设计 对于最后需要的裁片设计上的尺寸…...
Linux 配置 MySQL 定时自动备份到另一台服务器
Linux 配置 MySQL 定时自动备份到另一台服务器 前言1、配置服务器通信1.1:配置过程 2、编写自动备份sh脚本文件3:设置定时自动执行 前言 此方案可使一台服务器上的 MySQL 中的所有数据库每天 0 点自动转储为 .sql 文件,然后将文件同步到另一…...
PostgreSQL 备库的延迟问题
目录标题 1. 查看主备状态计算方式:实际情况:举个例子: 2. 查看历史状态3. 分析日志文件4. 查看数据库层面的复制状态5. 检查活动事务6. 检查系统资源7. 检查网络状况8. 检查复制槽状态9. 检查未提交的两阶段事务 要排查 PostgreSQL 备库的延…...
力扣-二叉树-226 翻转二叉树
思路 利用递归的思路 代码 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root nullptr){return root;}swap( root->right, root->left);invertTree(root->left);invertTree(root->right);return root;} };...
基于SpringBoot的在线车辆租赁信息管理系统
系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的不断发展和人们生活水平的提高,汽车租赁行业迎来了前所未有的发展机遇。传统的汽车租赁方式往往存在流程繁琐、信息不透明等问题,难以满足现代消费者对于便捷、高效服务的需求。因此&…...
掌握 systemd:Linux 服务管理的核心工具
1. 什么是 systemd? 定义:systemd 是 Linux 系统的初始化系统(init system)和服务管理器,用于替代传统的 SysVinit。核心目标: 加速系统启动(并行化任务)。统一管理服务、日志、挂载…...
【信息系统项目管理师-案例真题】2019下半年案例分析答案和详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题 1】(6 分)【问题 2 】(8 分)【问题 3 】(11 分)试题二【问题 1】(5分)【问题 2】 (14 分)【问题 3 】(6 分)试题三【问题 1】(8 分)【问题 2 】(6 分)【问题 3】 (8 分)【问题 4 …...
C/C++程序的内存是如何开辟的?
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴…...
日志结构化处理:PO对象toString日志转JSON工具
日志结构化处理:PO对象toString日志转JSON工具 1. 解决的问题2. 下载地址 在Java项目中,PO(Plain Old Java Object)对象遍布各个角落,且常常伴随着大量的日志记录需求。传统的做法是通过toString方法直接打印这些对象&…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
