Seata服务搭建与模式实现

日升时奋斗,日落时自省 

目录

1、简述

2、Seata优越性

3、Seata组成

4、Seata模式

4.1、XA 模式

4.2、AT 模式(默认模式)

4.3、TCC 模式

4.4、SAGA 模式

4.5、XA协议

5、Seata服务部署

5.1、文件数据源部署

5.1.1、下载并安装Seata

5.1.2、启动Seata服务

5.2.2、修改配置文件

5.2.3、Nacos中新增Seata配置

5.2.4、MySQL中新建Seata数据库

5.2.5、启动Seata服务

6、Seata模式实现

6.1、实现XA模式

6.1.1、添加Seata依赖

6.1.2、配置Seata信息

6.1.3、开启分布式事务

 6.2、实现AT模式

6.2.1、新增undo_log表

6.2.2、设置AT模式

 6.3、实现TCC模式

6.3.1、新建冻结表

6.3.2、新建TCC接口

6.3.3、新建TCC实现类

Try(T)中实现逻辑

Confirm(C)中实现逻辑

Cancel(C)中实现逻辑

6.4、Saga模式实现

 7、注意事项

7.1、Seata的JDK版本要求

7.2、AT模式注意


1、简述

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

注:因为注解@Transactional是不能满足分布式需求的

分布式事务定义:在分布式系统下,一个业务跨越多个服务或数据源,每个服务各自都是一个分支事务,要保证所有分支事务最终状态的一致性这样的事务就是分布式事务。

2、Seata优越性

本地事务:本地事务只能针对单个数据库的主要原因是,事务的原子性和一致性是基于数据库连接的。在一个数据库连接上执行的多个操作可以通过本地事务来保证原子性和一致性,因为它们共享同一个数据库连接和事务上下文。

分布式事务(Seata):分布式事务是通过将多个本地事务组合成一个全局事务,确保所有涉及的数据库或服务在一个事务中要么全部成功,要么全部回滚。分布式事务的实现需要一个统一的事务管理中心,用于协调和管理多个服务之间的事务操作。Seata 就是一个分布式事务解决方案,可以帮助处理分布式环境中的事务一致性问题(也就是数据一致性和可靠性)。

3、Seata组成

事务协调者 (Transaction Coordinator) : 简称 TC,它就是 Seata服务端,负责协调并管理分布式事务的执行。它是分布式事务的协调器,协调多个参与者的事务操作。事务协调者负责全局事务的创建、提交、回滚以及事务的状态管理。它通过全局事务 ID 来跟踪和协调分支事务的执行。

事务管理器(Transaction Manager) : 简称 TM,负责管理应用程序的本地事务 (分支事务)。事务管理器定义了全局事务的范围,负责将分支事务注册到全局事务中,并在全局事务的协调下,执行本地事务的提交或回滚。

资源管理器 (Resource Manager) : 简称 RM,管理分支事务处理的资源,与 TC 交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚

如下图所示:

4、Seata模式

Seata有以下四种模式:

4.1、XA 模式

它的性能相比其他事务模式要差一点,但能保证最严格的数据一致性。XA 模式需要设置为串行化隔离级别,相当于对数据添加了读写锁。另外连接资源需要在整个事务期间保持,这样可能会导致资源锁定问题,从而影响并发事务吞吐.

优点:实现简单、无业务侵入

缺点:性能差、必须实现 XA 协议、容易产生死锁

适用场景:隔离级别要求高,强一致性分阶段事务模型,牺牲了一定的可用性(保证了强一致性)

强一致性:就是同步执行,我的每一步都需要你等待,后续的所有流程执行结束,才会生效

4.2、AT 模式(默认模式)

解决了 XA 模式中锁占用时间过长的问题。它的主要特点是简单无侵入,强一致,学习成本低。缺点是需要遵守一定的开发规约,它并不是对所有的 SOL 类型都支持,有一定的使用限制。适应于通用的业务场景,但它并不适应于热点数据的高并发场景,像 SKU (Stock Keeping Unit,库存管理中的一个概念,用来唯一标识一个可售卖的商品)的库存的扣减。因为 AT 模式有应用层的全局锁,当需要对相同的数据修改操作时,需要使用全局锁控制事务的并发时序,实现上存在锁排队等待的机制。

优点: 简单、无业务侵入、事务强一致、学习成本低、性能高于 XA 模式D

缺点: 连接数据库支持(本地)事务、遵循一定的开发规范(Java 应用、通过JDBC 访问数据库)。

适用场景:通过场景,不适用于连接的数据库不支持 (本地)事务。

4.3、TCC 模式

业务层面的分布式事务解决方案,TCC,Try-Confirm-Cancel 模式,是一种通过三个步骤 (Try、Confirm、Cancel) 来实现分布式事务的模式。在 TCC 模式下,应用程序需要自行实现 Try、Confirm、Cance三个方法,分别表示尝试执行、确认提交和取消回滚。TCC 模式,不依赖于底层数据资源的事务支持:
一阶段 prepare 行为: 调用自定义的 prepare 逻辑
二阶段 commit 行为: 调用自定义的 commit 逻辑
二阶段 rollback 行为: 调用自定义的 rollback 逻辑
所谓 TCC 模式,是指支持把自定义的分支事务纳入到全局事务的管理中

优点: 灵活、性能高 (不依赖全局锁、不需要生成快照) 、不依赖数据库事务

缺点:业务侵入大、实现难度高 (自己实现事务操作的业务代码)、事务最终一致性 (不是强一致性)。

适用场景: 连接的数据库不支持 (本地)事务。

4.4、SAGA 模式

业务层面的分布式事务解决方案。个基于长事务的解决方案,Saga 模式解决的是在没有二阶段提交的情况下解决分布式事务。它的核心思想是将一个业务流程中的长事务拆分成多个本地短事务,业务流程中的每个参与者都真实的提交本地短事务,当其中有一个参与者的事务执行失败,则通过补偿机制补偿给前面已经执行成功的参与者

优点: 灵活、性能高、可异步化。

缺点: 无锁、不保证隔离性、业务侵入大

适用场景: 长事务

注:相比而言,以基于数据库事务划分XA和AT归为一类,TCC和SAGA归为一类(AT比较常用,TCC和SAGA很用)

4.5、XA协议

XA 协议是一种标准的分布式事务协议,用于实现跨多个资源管理器(如数据库)的分布式事务的一致性。

XA 协议定义了在分布式环境下多个资源 (如数据库)之间进行事务协作的规范和接口。它使得每个资源管理器都能参与到全局事务中,并根据全局事务的指令进行相应的操作

XA 协议的核心是两阶段提交 (Two-Phase Commit,2PC) 机制:

第一阶段(准备阶段): 全局事务协调器向所有参与者发送准备请求,每个参与者执行本地事务并返回确认信息给协调器。如果所有参与者都返回成功,那么协调器进入第二阶段。如果有任何一个参与者返回失败,协调器将发送回滚请求。

第二阶段(提交/滚阶段) : 全局事务协调器根据第一阶段的反馈情况,决定提交或回滚全局事务。首先,协调器发送提交或回滚指令给所有参与者,然后参与者按照指令执行相应的操作。

如下图展示的是:两种情况,事务协调者给出的不同的结果

4.6、XA和AT的区别

基本有三个区别:

  • XA模式一阶段(1PC)不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源
  • XA模式依赖数据库机制实现回滚;AT模式利用数据快照由Seata实现数据回滚
  • XA模式强一致,而AT模式最终一致

5、Seata服务部署

注:就是搭建TC服务,也叫做事务协调者

5.1、文件数据源部署

5.1.1、下载并安装Seata

直接去GitHub上找一下Seata下载个版本就行 ,我这里也提供给友友们一份网盘的1.7.0版

我们这里就采用1.7.0版本的

解压后里面的内容如上:

每个文件夹对应的作用:

  • bin:存放启动Seata Server的脚本文件
  • conf:Seata Server的配置目录
  • lib:Seata Server的Jar包存放目录
  • logs:存放日志文件

5.1.2、启动Seata服务

解压之后进入bin目录,双击 seata-server.bat就会启动了

双击相当于cmd在该路径下 输入 seata-server.bat -p 8091 -m file

Seata默认是以8091为端口号,file作为数据源

5.2.2、修改配置文件

修改conf/application.yml配置如下:

需要配置就是seata的是下的config,register,store数据库

注:可以从配置文件样例中找到相关配置,复制拷贝过来就行,需要改动就是访问地址 、用户名、密码

server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:username: seatapassword: seata
seata:config:# nacos配置type: nacosnacos:server-addr: localhost:8848namespace:group: DEFAULT_GROUPusername: nacospassword: nacoscontext-path:##if use MSE Nacos with auth, mutex with username/password attribute#access-key:#secret-key:data-id: seataServer.propertiesregistry:# nacos注册type: nacospreferred-networks: 30.240.*nacos:application: seata-serverserver-addr: localhost:8848group: DEFAULT_GROUPnamespace:cluster: defaultusername: nacospassword: nacoscontext-path:##if use MSE Nacos with auth, mutex with username/password attribute#access-key:#secret-key:store:# db 数据库mode: dbsession:mode: dblock:mode: dbdb:datasource: druiddb-type: mysqldriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=trueuser: rootpassword: 123456     min-conn: 10max-conn: 100global-table: global_tablebranch-table: branch_tablelock-table: lock_tabledistributed-lock-table: distributed_lockquery-limit: 1000max-wait: 5000
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login

 5.2.3、Nacos中新增Seata配置

将Seata存储修改为数据库

内容比较多, ctrl+F找一下相关内容如下:

需要改:

  • url:自己数据库路径
  • user:数据库用户
  • password:数据库密码 

注:这里seata库,下面会告诉友友们如何找,如何创建的

 5.2.4、MySQL中新建Seata数据库

首先在本地数据库需要创建一个库叫做的seata(与上面配置数据库信息对应),然后执行mysql.sql脚本

我这里使用workbeach来给友友们演示(以下四个表)

其中表的含义:

  • global_table:全局事务表
  • branch_table:分支事务表
  • lock_table:全局锁表
  • distributed_lock:分支事务锁表(多服务集群下保证同时只有一个服务处理提交或回滚)

5.2.5、启动Seata服务

注:前面配置Nacos,所以在启动Seata之前需要先启动Nacos

进入到seata/bin目录,在路径位置输入cmd,其实双击seata-server.bat就行(开放端口7091)

控制台页面访问路径:localhost:7091

登录信息账户和密码都是seata,其实这个控制台基本用不到,用户和密码可以在config/application.yml中配置

6、Seata模式实现

这里准备了一个微服务项目,使用Spring Cloud多模块项目,以用户购买商品的业务逻辑

两个微服务提供支持:(项目在前面的网盘已经提供,项目名seata-demo)

  • 库存服务:对给定的商品扣除库存数量
  • 订单服务:根据采购需求创建订单

6.1、实现XA模式

注:基于XA协议的流程

注:1开头的表示第一阶段,2开头表示第二阶段

XA模式执行流程:(这里偷个懒,直接拿官网的图给友友们解释)

XA模式实现需要以下3步:

  • 添加Seata依赖
  • 配置Seata信息
  • 开启分布式事务

6.1.1、添加Seata依赖

        <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>

6.1.2、配置Seata信息

seata:application-id: seata-demo-businessregistry:type: nacosnacos:server-addr: localhost:8848namespace: ""group: DEFAULT_GROUPapplication: seata-serverusername: nacospassword: nacostx-service-group: seata_tx_groupservice:vgroup-mapping:seata_tx_group: defaultdata-source-proxy-mode: XA

 配置解析:

  • application-id:表示一个事务id,多个是服务相关一个事务,用同一个id
  • registry:配置注册中心
  • type:配置注册中心类型(与seata配置文件相同)
  • nacos:相关配置
  • application:由于我们配置seata的注册中心为nacos启动后seata会注册到nacos中服务名称叫做seata-server
  • tx-service-group:事务组(被一个集群管理)这个是自己写的
  • seata_tx_group:与上面是对应的,默认使用事务组
  • data-source-proxy-mode:运行模式

6.1.3、开启分布式事务

需要使用@GlobalTransactional注解开启分布式事务,体现代码business服务中service层businessService(就是在调用两个库存的方法上添加全局事务注解)

    @GlobalTransactionalpublic void purchase(String userId,String commodityCode,Integer orderCount) {// 减库存storageService.deduct(commodityCode, orderCount);// 添加订单orderService.create(userId, commodityCode, orderCount);// 更新账户(代码省略...)}

 6.2、实现AT模式

AT模式执行流程如下:

还是基于XA执行流程来的,就是添加了一个表交undo_log表,用来存放执行SQL 的

注:提交事务就删除undo_log表的业务sql内容,回滚就让undo_log生成的逆sql恢复数据

AT模式多执行的两步:

  • 在数据库中添加undo_log事务回滚
  • 设置Seata运行模式为AT模式(或者删除运行模式,因为Seata默认就是AT模式)

6.2.1、新增undo_log表

这表网盘资料已经提供了(如果涉及到多个数据库,undo_log表每个涉及事务数据库都需要有该表)

在业务系统(TM事务管理器的项目)中,添加undo_log表,实现SQL

表的信息就是分支信息,内容状态修改id等(字段信息就是表达意思)

6.2.2、设置AT模式

只用修改 data-source-proxy-mode: AT 详细解释看XA模式配置解释(都是一样的)

seata:application-id: seata-demo-businessregistry:type: nacosnacos:server-addr: localhost:8848namespace: ""group: DEFAULT_GROUPapplication: seata-serverusername: nacospassword: nacostx-service-group: seata_tx_groupservice:vgroup-mapping:seata_tx_group: defaultdata-source-proxy-mode: AT

 6.3、实现TCC模式

TCC模式执行流程:

 基本如下四步:

  • 创建仓库(冻结表)
  • 新建TCC接口,声明TCC调用方法
  • 新建TCC实现类,实现方法
  • 将调用方法更改为TCC实现类的方法

注:执行思路借用XA基本思想,只是预备、提交、回滚需要自己去写,数据存放在冻结表,如果如果数据正常就提交,并清空冻结表,如果需要回滚,从冻结表中取进行恢复,将冻结数量设置为0

6.3.1、新建冻结表

TCC模式服务仓库,在服务项目下创建(网盘中也提供了)

6.3.2、新建TCC接口

@LocalTCC开启TCC模式,注解TwoPhaseBusinessAction的三个参数:

value:try预备资源

commitMethod:如果是提交执行那个方法(写方法名)

rollbackMethod:如果是回滚执行那个方法(写方法名)

deduct中注解是为了对应TCC,注解参数

@LocalTCC
public interface TCCService {/** try 逻辑和二阶段方法声明* */@TwoPhaseBusinessAction(name = "deduct",commitMethod = "confirm",rollbackMethod = "cancel")void deduct(@BusinessActionContextParameter(paramName = "commodityCode")String commodityCode,@BusinessActionContextParameter(paramName = "orderCount")Integer orderCount);/** 二阶段 提交方法* */boolean confirm(BusinessActionContext context);/** 二阶段回滚方法* */boolean cancel(BusinessActionContext context);
}

6.3.3、新建TCC实现类

TCC每个方法中实现逻辑业务

Try(T)中实现逻辑

扣减库存

仓库冻结表中添加数据

Confirm(C)中实现逻辑

根据XID(事务ID)删除冻结表的数据

Cancel(C)中实现逻辑

修改仓库,恢复冻结数量

修改冻结表的状态为2,冻结数量为0

注:具体实现项目中有库存服务中service层有Imp实现类,TCCServiceImpl类进行方法实现

6.4、Saga模式实现

Saga实现流程:

给友友们解释一下:

T表示事务执行,C表示事务回滚,后面的数字用来区分事务,箭头表示事务之间有关系

当T3事务失败时,就会进行回滚事务C3在回滚C2最后的回滚到C1

 前面提到TCC和SAGA是比较类似,不需要数据库有事务功能,这里不在实现Saga

有想法的友友可以去官网看看:https://seata.io/zh-cn/docs/user/mode/saga

 7、注意事项

7.1、Seata的JDK版本要求

稳定支持JDK8,11,其余可能会有问题

7.2、AT模式注意

  • 支持数据库:mysql、Oracle、pgsql、mariadb
  • 所有业务库都需要undo_log表(针对分库)
  • 分布式事务中,消费者需要依赖、配置、注解,提供者可以不加全局事务注解、但是必须有依赖和配置

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

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

相关文章

Ts自封装WebSocket心跳重连

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;允许客户端和服务器之间进行双向实时通信。 所谓心跳机制&#xff0c;就是在长时间不使用WebSocket连接的情况下&#xff0c;通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手…

HarmonyOS4.0系统性深入开发11通过message事件刷新卡片内容

通过message事件刷新卡片内容 在卡片页面中可以通过postCardAction接口触发message事件拉起FormExtensionAbility&#xff0c;然后由FormExtensionAbility刷新卡片内容&#xff0c;下面是这种刷新方式的简单示例。 在卡片页面通过注册Button的onClick点击事件回调&#xff0c;…

数据库中的时间和前台展示的时间不一样,如何保存日期格式的数据到数据库? 如何展示数据库的日期数据到前台

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; ✈️公众号 | 热爱技术的小郑 文章底部有个人公众号二维码。回复 Java全套视频教程 或 前端全套视频教程 即可获取 300G 教程资料…

【深入浅出RocketMQ原理及实战】「云原生升级系列」打造新一代云原生“消息、事件、流“统一消息引擎的融合处理平台

打造新一代云原生"消息、事件、流"统一消息引擎的融合处理平台 云原生架构RocketMQ的云原生架构实现RocketMQ的云原生发展历程互联网时期的诞生无法支持云原生的能力 云原生阶段的升级云原生升级方向促进了Mesh以及多语言化发展可分合化的存算分离架构存储分离架构的…

听GPT 讲Rust源代码--library/portable-simd

File: rust/library/portable-simd/crates/core_simd/examples/spectral_norm.rs spectral_norm.rs是一个示例程序&#xff0c;它展示了如何使用Portable SIMD库中的SIMD&#xff08;Single Instruction Multiple Data&#xff09;功能来实现频谱规范化算法。该示例程序是Rust源…

跟着cherno手搓游戏引擎【2】:日志系统spdlog和premake的使用

配置&#xff1a; 日志库文件github&#xff1a; GitHub - gabime/spdlog: Fast C logging library. 新建vendor文件夹 将下载好的spdlog放入 配置YOTOEngine的附加包含目录&#xff1a; 配置Sandbox的附加包含目录&#xff1a; 包装spdlog&#xff1a; 在YOTO文件夹下创建…

在Django中配置PostgreSQL

下载并安装PostgreSQL PostgreSQL: Downloads 安装依赖psycopg2 python -m pip install psycopg2 修改Django配置文件settings.py &#x1f4cc;编辑 mysite/settings.py 文件前&#xff0c;先设置 TIME_ZONE 为你自己时区。 LANGUAGE_CODE zh-Hans TIME_ZONE Asia/Shang…

【Elasticsearch源码】 分片恢复分析

带着疑问学源码&#xff0c;第七篇&#xff1a;Elasticsearch 分片恢复分析 代码分析基于&#xff1a;https://github.com/jiankunking/elasticsearch Elasticsearch 8.0.0-SNAPSHOT 目的 在看源码之前先梳理一下&#xff0c;自己对于分片恢复的疑问点&#xff1a; 网上对于E…

【基础】【Python网络爬虫】【12.App抓包】reqable 安装与配置(附大量案例代码)(建议收藏)

Python网络爬虫基础 App抓包1. App爬虫原理2. reqable 的安装与配置reqable 安装教程reqable 的配置 3. 模拟器的安装与配置夜神模拟器的安装夜神模拟器的配置配置代理配置证书 4. 内联调试及注意事项软件启动顺开启抓包功reqable面板功列表部件功能列表数据快捷操作栏 夜神模拟…

WPF+Halcon 培训项目实战 完结(13):HS 鼠标绘制图形

文章目录 前言相关链接项目专栏运行环境匹配图片矩形鼠标绘制Halcon添加右键事件Task封装运行结果个人引用问题原因推测 圆形鼠标绘制代码运行结果 课程完结&#xff1a; 前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原因无非是想换个工作。相关的教学视…

【java爬虫】股票数据获取工具前后端代码

前面我们有好多文章都是在介绍股票数据获取工具&#xff0c;这是一个前后端分离项目 后端技术栈&#xff1a;springboot&#xff0c;sqlite&#xff0c;jdbcTemplate&#xff0c;okhttp 前端技术栈&#xff1a;vue&#xff0c;element-plus&#xff0c;echarts&#xff0c;ax…

K8s实战入门

1.NameSpace Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 默认情况下&#xff0c;kubernetes集群中的所有的Pod都是可以相互访问的。但是在实际中&#xff0c;可能不想让两个Pod之间进行互相…

在线智能防雷监控检测系统应用方案

在线智能防雷监控检测系统是一种利用现代信息技术&#xff0c;对防雷设施的运行状态进行实时监测、管理和控制的系统&#xff0c;它可以有效提高防雷保护的安全性、可靠性和智能化程度&#xff0c;降低运维成本和风险&#xff0c;为用户提供全方位的防雷解决方案。 地凯科技在…

排序算法之计数排序

计数排序是一种非基于比较的排序算法&#xff0c;它通过统计数组中每个元素出现的次数&#xff0c;将其按次数从小到大排序。 以下是计数排序的基本步骤&#xff1a; 统计&#xff1a;统计数组中每个元素出现的次数。计数&#xff1a;将每个元素的出现次数存储在另一个数组中…

redisson作为分布式锁的底层实现

1. redisson如何实现尝试获取锁的逻辑 如何实现在一段的时间内不断的尝试获取锁 其实就是搞了个while循环&#xff0c;不断的去尝试获取锁资源。但是因为latch的存在会在给定的时间内处于休眠状态。这个事件&#xff0c;监听的是解锁动作&#xff0c;如果解锁动作发生。会调用…

Android textview展示富文本内容

今天实现的内容&#xff0c;就是上图的效果&#xff0c;通过Span方式展示图片&#xff0c;需要支持文字颜色改变、加粗。支持style\"color:green; font-weight:bold;\"展示。尤其style标签中的font-size、font-weight是在原生中不被支持的。 所以我们今天需要使用自…

病情聊天机器人,利用Neo4j图数据库和Elasticsearch全文搜索引擎相结合

项目设计目的&#xff1a; 本项目旨在开发一个病情聊天机器人&#xff0c;利用Neo4j图数据库和Elasticsearch全文搜索引擎相结合&#xff0c;实现对病情相关数据的存储、查询和自动回答。通过与用户的交互&#xff0c;机器人可以根据用户提供的症状描述&#xff0c;给出初步的可…

字母简化(UPC练习)

题目描述 给出一串全部为小写英文字母的字符串&#xff0c;要求把这串字母简化。简化规则是&#xff1a;统计连续出现的字母数&#xff0c;输出时先输出个数&#xff0c;再输出字母。比如&#xff1a;aaabbbaa&#xff0c;则简化为3a3b2a&#xff1b;而zzzzeeeeea&#xff0c;…

帆软报表中定时调度中的最后一步如何增加新的处理方式

在定时调度中,到调度执行完之后,我们可能想做一些别的事情,当自带的处理方式不满足时,可以自定义自己的处理方式。 产品的处理方式一共有如下这些类型: 我们想在除了上面的处理方式之外增加自己的处理方式应该怎么做呢? 先看下效果: 涉及到两方面的改造,前端与后端。…

前端算法之二叉树

二叉树 二叉树用于解决什么问题 数据的组织与搜索&#xff1a;排序&#xff1a;表达式和计算&#xff1a;图形处理&#xff1a; 举例&#xff1a;二叉树的最近公共祖先 思路&#xff1a; 排序/排布方式 和 &#xff08;排序中&#xff09;当前树和节点的关系 举例2&#xff1a;…