从安装 Seata 开始的分布式事务之旅 springboot集成seata
从安装 Seata 开始的分布式事务之旅
- 介绍
- 什么是 Seata?
- 安装 Seata Server
- 下载 Seata Server 发行版
- 配置Seata
- 解压文件
- 配置Seata的yml文件
- 把配置文件config.txt加载到nacos上
- 修改config.txt文件
- 加载到nacos上
- 启动Seata服务
- 正常启动
- 查看启动日志
- 打开控制台页面
- 启动时遇到的坑
- 无法解析${console.user.username}的值
- 无法解析${seata.security.secretKey}的值
- 数据库连接问题
- 在 Spring Boot 项目中集成 Seata
- 工作环境
- cloud、boot、alibaba环境
- 添加依赖
- 配置yml
- 业务代码中集成 Seata
- 使用 `@GlobalTransactional` 注解管理全局事务
- 演示 AT(自动补偿)模式和 TCC(两阶段提交)模式
- 使用 AT(自动补偿)模式
- 使用 TCC(两阶段提交)模式
- 集成Seata踩的坑
- Table 'ddz.undo_log' doesn't exist
- no available service 'null' found, please make sure registry config correct
- 分布式事务未生效
- dynamic-datasource can not find primary datasource
- Communications link failure
- 总结
- 参考资料

介绍
什么是 Seata?
在现代应用程序开发中,分布式系统的应用越来越广泛。然而,随着系统的复杂性增加,处理分布式事务变得愈发困难。这就是 Seata 出现的背景。Seata(Simple Extensible Autonomous Transaction Architecture)是一种开源的分布式事务解决方案,旨在解决分布式系统中的事务一致性和协调性问题。
在传统的单体应用中,通常使用关系型数据库来管理事务,保证数据的一致性。但在分布式系统中,由于涉及多个独立的服务,事务管理变得复杂。分布式事务的要求是:所有涉及的服务要么都成功提交,要么都回滚,以保持数据的一致性。
Seata 提供了两种主要的事务模式:
-
AT 模式(自动补偿模式):在 AT 模式中,Seata会自动补偿事务,无需手动编写补偿逻辑。Seata会将事务的所有操作编排成一个全局的事务,然后执行各个分支的 try 操作,在出现异常时执行相应的补偿操作。
-
TCC 模式(两阶段提交模式):TCC 模式要求开发者手动编写 Try、Confirm 和 Cancel 三个阶段的逻辑。在 TCC 模式中,Seata负责协调全局事务的提交和回滚,而各个分支的 try、confirm 和 cancel 操作则由开发者来实现。
Seata 还提供了可扩展的注册中心和存储支持,使其适用于各种不同的场景。
总的来说,Seata 是一个强大的分布式事务解决方案,可以帮助开发者解决分布式事务的难题,确保分布式系统中数据的一致性和可靠性。通过集成 Seata,开发者可以更加轻松地构建复杂的分布式应用,提升系统的稳定性和性能。
安装 Seata Server
下载 Seata Server 发行版
您可以从 Seata 官方网站下载最新的 Seata Server 发行版,并解压到指定目录;有源码和二进制版本,我们这里选择安装二进制文件下载。我的版本是1.7.0 (2023-07-11,推荐版本)

配置Seata
解压文件

下载下来的是zip文件,解压后是上面文件夹,默认文件夹名字是seata。
配置Seata的yml文件
进入seata/conf目录下,这里有两个配置文件; 我们需要把application.yml 随意修改一个名字;然后再 application.example.yml修改成application.yml 作为主要配置文件。

修改 application.yml文件,我这里使用的nacos作为注册中心,所以需要修改的地方有:
- seata:config:type
- seata:registry:type
- store:mode
- store:session:mode
- store: lock:mode
- store:db 数据库的配置修改成自己的
配置文件:
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_logstash
# 这里是主要的配置文件
seata:config:# support: nacos 、 consul 、 apollo 、 zk 、 etcd3type: nacosnacos:server-addr: 127.0.0.1:8848# 如果在nacos上添加了命名空间,则配置命令空间IDnamespace:# 配置分组group: SEATA_GROUPusername:password:context-path:##if use MSE Nacos with auth, mutex with username/password attribute#access-key:#secret-key:data-id: seataServer.propertiesregistry:# support: nacos 、 eureka 、 redis 、 zk 、 consul 、 etcd3 、 sofatype: nacospreferred-networks: 30.240.*nacos:application: seata-serverserver-addr: 127.0.0.1:8848group: SEATA_GROUPnamespace:cluster: defaultusername:password:context-path:##if use MSE Nacos with auth, mutex with username/password attribute#access-key:#secret-key:server:service-port: 8091 #If not configured, the default is '${server.port} + 1000'max-commit-retry-timeout: -1max-rollback-retry-timeout: -1rollback-retry-timeout-unlock-enable: falseenable-check-auth: trueenable-parallel-request-handle: trueretry-dead-threshold: 130000xaer-nota-retry-timeout: 60000enableParallelRequestHandle: truerecovery:committing-retry-period: 1000async-committing-retry-period: 1000rollbacking-retry-period: 1000timeout-retry-period: 1000undo:log-save-days: 7log-delete-period: 86400000session:branch-async-queue-size: 5000 #branch async remove queue sizeenable-branch-async-remove: false #enable to asynchronous remove branchSessionstore:# support: file 、 db 、 redismode: 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: mysqlpassword: mysqlmin-conn: 10max-conn: 100global-table: global_tablebranch-table: branch_tablelock-table: lock_tabledistributed-lock-table: distributed_lockquery-limit: 1000max-wait: 5000metrics:enabled: falseregistry-type: compactexporter-list: prometheusexporter-prometheus-port: 9898transport:rpc-tc-request-timeout: 15000enable-tc-server-batch-send-response: falseshutdown:wait: 3thread-factory:boss-thread-prefix: NettyBossworker-thread-prefix: NettyServerNIOWorkerboss-thread-size: 1
把配置文件config.txt加载到nacos上
修改config.txt文件
config.txt文件在seata/script/config-center目录下;我们需要修改的地方有:
- store.mode=db
- store.lock.mode=db
- store.session.mode=db
- store.db 数据库的配置修改成自己的,和上面yml文件里面的一样
加载到nacos上
进入seata/script/config-center/nacos 目录下执行nacos-config.sh文件。
sh nacos-config.sh -h 121.37.228.169 -p 8848 -g SEATA_GROUP -t 0af6e97b-a684-4647-b696-7c6d42aecce7 -u nacos -w nacos
- -h: Nacos IP地址
- -p: Nacos端口号
- -g: Group分组名
- -t: 命名空间ID,没有则默认public
- -u: 用户名
- -w:密码
执行完成时候登录我们的Nacos配置管理就能查看到加载好的数据:

启动Seata服务
正常启动
进入seata/bin 目录下,执行命令:
sh seata-server.sh

这里我启动的时候可以会遇到报异常的情况,下面我出了几种我在启动时遇到的一些坑。可以移步到 启动时遇到的坑
查看启动日志
我的是Mac系统所有是open打开日志文件,其他的系统需要根据系统来执行命令,或者直接进入seata/logs目录下查看start.out文件。
open /Users/ddz/Downloads/seata/logs/start.out

能看到日志输出地址说明启动成功了。
打开控制台页面
控制台页面,默认账号密码是 seata/seata。

启动时遇到的坑
这里是我在部署Seata中遇到的一些坑,可能和有不同的地方只做为参考。
无法解析${console.user.username}的值
异常信息: Could not resolve placeholder ‘console.user.username’ in value “${console.user.username}”

解决方法:需要把之前修改成其他名称的yml文件中console下的所有配置信息复制到现在的application.yml下。这里就是设置我们登录控制台页面的账号密码。
无法解析${seata.security.secretKey}的值
异常信息:Could not resolve placeholder ‘seata.security.secretKey’ in value “${seata.security.secretKey}”

解决方法:需要把之前修改成其他名称的yml文件中seata.security下的所有配置信息复制到现在的application.yml下。
数据库连接问题
异常信息:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
在MySQL5.7之前的版本,安全性较低,存在任何用户都可以连接上数据库,所以官方在5.7版本加大了对隐私的保护。并且采用了默认 useSSL = true值防止对数据库的随意修改,到了8.0版本,仍然保留了SSL,并且默认值为 true。

解决方法:在数据库配置url后追加&useSSL=false;需要检查yml配置文件和Nacos上配置列表中store.db.url。

在 Spring Boot 项目中集成 Seata
上面我们介绍了如何在本地安装seata服务端,接下来介绍一下我们Spring Boot项目中集成seata;这里我只单纯的用一个demo来介绍,可根据自己的业务逻辑来进行实现。
工作环境
- MySQL 5.7.28
- Maven 3.5.4
- JDK 1.8
- Mybatis 3.4.1
- dynamic 3.4.1
cloud、boot、alibaba环境
<spring-boot.version>2.3.7.RELEASE</spring-boot.version><spring-cloud.version>Hoxton.SR9</spring-cloud.version><spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
添加依赖
<!-- MySQL --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Mybatis --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><!-- 多数据源 --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.4.1</version></dependency><!-- Seata分布式事务 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>
配置yml
server:port: 7001
spring:application:name: ddz-usercloud:nacos:discovery:# 服务分组group: ddzserver-addr: 121.37.228.111:8848# 必须填命名空间的ID
# namespace: 9ebef975-dcc0-4430-9c63-1c62d8a86d82datasource:dynamic:# 开启seata分布式事务seata: truestrict: falseprimary: masterdatasource:master:url: jdbc:mysql://121.37.228.111:3306/ddz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=trueusername: ddzpassword: ddz2023local:url: jdbc:mysql://127.0.0.1:3306/ddz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=trueusername: rootpassword: ddz2023# MyBatis Plus配置
mybatis-plus:# 搜索指定包别名typeAliasesPackage: com.ddz.**.entity# 配置mapper的扫描,找到所有的mapper.xml映射文件mapperLocations: classpath*:mapper/**/*.xmlglobal-config:db-config:id-type: autoconfiguration:# 开启驼峰,开启后,只要数据库字段和对象属性名字母相同,无论中间加多少下划线都可以识别map-underscore-to-camel-case: true# Seata 配置
seata:application-id: seata-server# 是否启用数据源bean的自动代理enable-auto-data-source-proxy: falsetx-service-group: default_tx_group # 必须和服务器配置一样registry:type: nacosnacos:# Nacos 服务地址server-addr: 121.37.228.111:8848group: SEATA_GROUP
# namespace: 9ebef975-dcc0-4430-9c63-1c62d8a86d82application: seata-server # 必须和服务器配置一样# username:# password:cluster: defaultconfig:type: nacosnacos:server-addr: 121.37.228.111:8848group: SEATA_GROUP
# namespace: 9ebef975-dcc0-4430-9c63-1c62d8a86d82service:vgroup-mapping:default_tx_group: default # 必须和服务器配置一样disable-global-transaction: falseclient:rm:# 是否上报成功状态report-success-enable: true# 重试次数report-retry-count: 5
业务代码中集成 Seata
我们根据两个数据源创建两个mapper类然后再controller中测试;我这里方便测试就省略了业务层。
使用 @GlobalTransactional 注解管理全局事务

演示 AT(自动补偿)模式和 TCC(两阶段提交)模式
使用 AT(自动补偿)模式
在 AT 模式中,Seata会自动补偿事务,无需手动编写补偿逻辑。首先,我们来演示一个简单的转账场景,将资金从一个账户转移到另一个账户,并保证事务的一致性。
- 添加 @GlobalTransactional 注解
在转账服务的方法上添加 @GlobalTransactional 注解来标记全局事务:
@Service
public class TransferService {@GlobalTransactionalpublic void transfer(String fromAccount, String toAccount, double amount) {// 扣除转出账户金额deductAmount(fromAccount, amount);// 增加转入账户金额addAmount(toAccount, amount);}// 实现扣除金额逻辑// ...// 实现增加金额逻辑// ...
}
- 测试 AT 模式
编写测试用例来验证 AT 模式的事务管理:
@RunWith(SpringRunner.class)
@SpringBootTest
public class TransferServiceTest {@Autowiredprivate TransferService transferService;@Testpublic void testTransfer() {// 假设从账户 A 转账 100 到账户 BtransferService.transfer("accountA", "accountB", 100.0);}
}
运行测试用例,观察转账是否成功,并查看日志确认 Seata 是否自动补偿了事务。
使用 TCC(两阶段提交)模式
在 TCC 模式中,我们需要手动编写 Try、Confirm 和 Cancel 三个阶段的逻辑,以确保事务的正确执行。下面我们来演示一个简单的订单创建场景,包括下单、扣减库存和创建订单三个阶段。
- 实现 TCC 接口
创建一个 TCC 接口并实现 Try、Confirm 和 Cancel 三个阶段的逻辑:
public interface OrderTccService {@GlobalTransactionalboolean createOrder(OrderDTO orderDTO);@TwoPhaseBusinessAction(name = "orderTccService", commitMethod = "confirmOrder", rollbackMethod = "cancelOrder")boolean tryCreateOrder(OrderDTO orderDTO);boolean confirmOrder(OrderDTO orderDTO);boolean cancelOrder(OrderDTO orderDTO);
}
- 实现 TCC 逻辑
在实现类中编写 TCC 逻辑:
@Service
public class OrderTccServiceImpl implements OrderTccService {@Overridepublic boolean tryCreateOrder(OrderDTO orderDTO) {// 预留库存逻辑// ...return true;}@Overridepublic boolean confirmOrder(OrderDTO orderDTO) {// 确认创建订单逻辑// ...return true;}@Overridepublic boolean cancelOrder(OrderDTO orderDTO) {// 取消创建订单逻辑// ...return true;}
}
- 测试 TCC 模式
编写测试用例来验证 TCC 模式的事务管理:
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderTccServiceTest {@Autowiredprivate OrderTccService orderTccService;@Testpublic void testCreateOrder() {// 创建一个订单OrderDTO orderDTO = new OrderDTO();// 设置订单信息// ...orderTccService.createOrder(orderDTO);}
}
运行测试用例,观察订单的创建是否成功,并查看日志确认 TCC 模式的 Try、Confirm 和 Cancel 阶段是否正确执行。
集成Seata踩的坑
这里是我在集成过程中遇到的一些坑,可能和有不同的地方只做为参考。
Table ‘ddz.undo_log’ doesn’t exist
异常信息:process connectionProxy commit error: Table ‘ddz.undo_log’ doesn’t exist。
解决方法:在数据源中切少Seata需要的日志表;在每个数据源中新增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;
no available service ‘null’ found, please make sure registry config correct
异常信息:出现这个的原因是我们没有把Seata的config.txt加载到nacos上。
解决方法:执行命令把配置加载到Nacos配置中心上。参考上面:把配置文件config.txt加载到nacos上
分布式事务未生效
原因:我们使用的dynamic多数据源,默认是没有开启Seata分布式事务的。
解决方法:在yml配置文件中的dynamic下添加seata: true配置以开启分布式事务。
dynamic-datasource can not find primary datasource
原因:出现这个是数据源配置信息错误,我这里出现这个异常的原因是我自己太不细心导致数据库连接(url)连接编写错了。
解决方法:仔细检查一下datasource 下面数据源的配置。
Communications link failure
原因:这里大部分原因是MySQL需要指明是否进行SSL连接,默认是开启SSL连接的。
解决方法:在数据库连接配置URL后追加&useSSL=false即可。
总结
随着分布式系统的不断发展,分布式事务领域也会不断进化。在未来,我们可以进一步探索更多的分布式事务模式和解决方案,以满足不同业务场景的需求。同时,Seata 作为一个活跃的开源项目,将会不断推出新的功能和改进,我们可以关注 Seata 社区的更新和贡献自己的力量。
此外,除了 Seata,还有其他一些分布式事务解决方案,例如 TCC-Transaction、SAGA、HSTC 等,这些方案也值得我们深入学习和探索。根据业务场景的不同,我们可以选择最合适的方案来解决分布式事务问题。
参考资料
Nacos 官方文档
Seata 官方文档
Spring Boot 官方文档
相关文章:
从安装 Seata 开始的分布式事务之旅 springboot集成seata
从安装 Seata 开始的分布式事务之旅 介绍什么是 Seata? 安装 Seata Server下载 Seata Server 发行版配置Seata解压文件配置Seata的yml文件把配置文件config.txt加载到nacos上修改config.txt文件加载到nacos上 启动Seata服务正常启动查看启动日志打开控制台页面 启动…...
Laravel 使用mix引入本地样式文件 报错 Unable to locate Mix处理
刚下了一个bootstrap样式文件,mix引入了一下,直接报错: Unable to locate Mix file: /css/bootstrap.min.css. (View: D:\phpEnv\www\abc\resources\views\admin\noteAdd.blade.php)原来是需要 npm run dev 启动一下 ✔ Compiled Successfu…...
QT学习笔记-QT安装oracle oci驱动
QT学习笔记-QT安装oracle oci驱动 0、背景1、环境以及条件说明2、编译驱动2.1 下载oracle instant client2.2 编译qt oci驱动2.2.1 修改oci.pro2.2.2 MinGW64构建套件编译2.2.3 MSVC2019_64构建套件编译 3、访问数据库运行成功 0、背景 在使用QT开发应用的过程中,往…...
【React学习】—类的基本知识(五)
【React学习】—类的基本知识(五) <script>// 创建一个Person类class Person{//构造器方法constructor(name,age){this.namename;this.ageage;}//一般方法speak(){//speak方法一般放在哪里?类的原型上,供实例使用//通过Pers…...
【AI】《动手学-深度学习-PyTorch版》笔记(十六):自定义网络层、保存/加载参数、使用GPU
AI学习目录汇总 1、自定义网络层 自定义网络层很简单,三步即可完成 继承类:nn.Module定义初始化函数:__init__中定义需要初始化的代码定义向前传播函数:forward1.1 不带参数的网络层 1)定义网络层 import torch import torch.nn.functional as F from torch import nn…...
微软杀入Web3:打造基于区块链的AI产品
作者:秦晋 2023年1月,微软向 ChatGPT 创建者 OpenAI 投资 100 亿美元,在AI业界引发格外关注。此举也让微软在AI的战略探索上提前取得有利位置。 2023年3月,微软软件工程师 Albacore 披露微软正在为Edge 浏览器测试内置的非托管加密…...
聊聊51单片机
目录 1.介绍 2.发展 3.应用领域 4.发展前景 1.介绍 51单片机(AT89C51)是一种常见的8位微控制器,属于Intel MCS-51系列。它是一种低功耗、高性能的单片机,广泛应用于嵌入式系统中。 51单片机具有很多特点和功能,例如…...
Linux yum 命令,Linux apt 命令
目录 Linux yum 命令 yum 语法 yum常用命令 实例 1 实例 2 实例 3 国内 yum 源...
Vue+SpringBoot项目开发:登录页面美化,登录功能实现(三)
写在开始:一个搬砖程序员的随缘记录上一章写了从零开始VueSpringBoot后台管理系统:Vue3TypeScript项目搭建 VueTypeScript的前端项目已经搭建完成了 这一章的内容是引入element-plus和axios实现页面的布局和前后端数据的串联,实现一个登陆的功能&#x…...
2.若依前后端分离版第一个增删查改
1.介绍 若依提供了代码生成功能,单表的CRUD可以直接用若依框架提供的代码生成进行创建。 2.实现 2.1 在数据库创建业务表test_teacher 2.2 生成代码 运行系统,进入菜单[系统工具]-》[代码生成],点击导入按钮,选择需要生成代码的表进行导…...
javaSE_2.2——【方法的介绍】
1.方法的定义 (1)方法声明的语法规则如下所示: [修饰符] 返回值类型 方法名称([参数列表]){// 方法体 } 方法修饰符:是一种关键字,用来描述方法、类、变量等各种元素的声明,一个程序可以同时拥有多个修饰…...
【02】基础知识:typescript数据类型
1、布尔类型 boolean let flag: boolean false2、数字类型 number let num: number 6 //十进制 let num2: number 0xf00d //十六进制 let num3: number 0b1010 //二进制 let num4: number 0o744 //八进制3、字符串类型 string 用双引号(“)或单引…...
DIP: NAS(Neural Architecture Search)论文阅读与总结(双份快乐)
文章地址: NAS-DIP: Learning Deep Image Prior with Neural Architecture SearchNeural Architecture Search for Deep Image Prior 参考博客:https://zhuanlan.zhihu.com/p/599390720 文章目录 NAS-DIP: Learning Deep Image Prior with Neural Architecture Search1. 方法…...
AI:02-基于深度学习的动物图像检索算法的研究
文章目录 一、算法原理二、代码实现三、实验结果四、总结深度学习在计算机视觉领域中的应用越来越广泛,其中动物图像检索算法是一个重要的应用场景。本文将介绍一种基于深度学习的动物图像检索算法,并提供相应的代码实现。 一、算法原理 本算法采用卷积神经网络(Convolutio…...
IDEA项目实践——Spring集成mybatis、spring当中的事务
系列文章目录 IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介 IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——动态SQL、关系映射、注解开发 IDEA项目实践——Spring框架简介,以及IOC注解 IDEA项目实践—…...
6-Ngnix配置反向代理
1.前提 虚拟机能连接外网 仿真http应用需在本虚拟机启用(原因:只有一台虚拟机做测试) http_8080和http_8081要启用(http测试应用) [rootcent79-2 ~]# ls -l http_* -rwxr-xr-x 1 root root 6391676 Jul 19 13:39 http_8080 -rwxr-xr-x 1 …...
构建 LVS-DR 群集、配置nginx负载均衡。
目录 一、基于 CentOS 7 构建 LVS-DR 群集 1、准备四台虚拟机 2、配置负载调度器(192.168.2.130) 3、部署共享存储(192.168.2.133) 4、配置两个Web服务器(192.168.2.131、192.168.2.132) 测试集群 二…...
【UE4的垃圾回收】
UE4的垃圾回收 1 UObjects及子类1.1 UObjects类包含UObjects成员(UPROPERTY)1.2 UObjects类包含非UObjects成员 2 非UObject及子类2.1 非UObjects类包含UObjects成员12.2 非UObjects类包含UObjects成员22.3 非UOjbects类包含非UObjects成员 3 UStructs4 …...
nginx负载均衡的几种配置方式介绍
一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备: 2.190均衡服务器,2.191web服务器1,2.160web服务器2,三台设备均安装nginx,两台web服务器均有网页内容 1.一般轮询负载均衡 (1)…...
uniapp发布插件显示components/xxx文件没找到,插件格式不正确
uniapp发布插件显示components/xxx文件没找到,插件格式不正确 将插件文件这样一起选中,然后右键压缩成zip文件,而不是外层文件压缩...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
Spring AOP代理对象生成原理
代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】,这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
HTML中各种标签的作用
一、HTML文件主要标签结构及说明 1. <!DOCTYPE html> 作用:声明文档类型,告知浏览器这是 HTML5 文档。 必须:是。 2. <html lang“zh”>. </html> 作用:包裹整个网页内容,lang"z…...
