Seata学习

系列文章目录

JavaSE
基础知识、数据类型学习万年历项目代码逻辑训练习题
代码逻辑训练习题方法、数组学习图书管理系统项目
面向对象编程:封装、继承、多态学习封装继承多态习题常用类、包装类、异常处理机制学习
集合学习IO流、多线程学习仓库管理系统JavaSE项目
员工管理系统、多表查询、反射实现DBHelper学习DML、DDL、数据库对象学习
JavaWeb
网络编程、各种标签、CSS学习ECMAScript、BOM学习DOM、jQuery学习
Servlet、JSP、Cookie、Ajax学习融资管理系统JavaWeb项目
框架
MyBatis框架学习逆向工程、Spring框架IOC、AOP学习SpringMVC框架学习
SpringBoot框架学习招聘网站框架项目Vue介绍、窗体内操作、窗体间操作学习
Vue路由配置、网络请求访问框架项目、element组件介绍学习标准管理系统Vue项目
微服务
Linux安装、Nginx反向代理、负载均衡学习Docker学习Jenkins学习
Nexus学习Spring Security学习RabbitMQ学习
Redis学习MongoDB学习Nacos学习
Spring Session学习Spring Gateway学习JSR 303学习
OenFeign学习Dubbo学习Hystrix学习
Sentinel学习JMeter学习Seata学习

文章目录

  • 系列文章目录
  • 前言
  • 一、Seata介绍
    • 1. Seata介绍
    • 2. 三个核心角色
    • 3. 四种分布式事务的解决方案
  • 二、Seata安装
    • 1. 拉取docker镜像
    • 2. 拷贝配置文件
      • 2.1 创建目录
      • 2.2 保存file.conf文件
    • 3. 启动nacos
    • 4. 保存registry.conf文件
    • 5. 创建config.txt文件
    • 6. 创建nacos-config.sh文件
    • 7. 导入nacos配置
    • 8. 复制配置文件
    • 9. 关闭并删除之前的seata容器
    • 10. 开启mysql容器
    • 11. 测试并创建连接
    • 11. 创建seata数据库
    • 12. 创建表
    • 13. 启动seata
  • 三、普通事务回滚
    • 1. 项目基础
    • 2. 更改application.yml内数据库连接属性
    • 3. 创建score数据库
    • 4. 运行项目
      • 4.1 正常运行
      • 4.2 异常运行测试回滚
    • 5. 添加普通的事务回滚
  • 四、Seata事务回滚
    • 1. 添加依赖
    • 2. 启动类添加注释
    • 3. 修改application.yml配置文件
    • 4. 更改事务注解
    • 5. 启动项目
      • 5.1 有错误时
      • 5.2 无错误时
  • 总结


前言

本文我们要讲述:
Seata
代码自取
通过网盘分享的文件:241005_seata.zip
链接: https://pan.baidu.com/s/1xTs4uV-3VAiRCPzBjd-Qow?pwd=k25m 提取码: k25m


一、Seata介绍

1. Seata介绍

Seata是一个用于管理分布式事务的开源框架,由阿里巴巴集团开发并维护。它提供了一套分布式事务解决方案,旨在解决分布式系统中的事务一致性问题。

2. 三个核心角色

事务协调者(Transaction Coordinator,TC):负责维护整个分布式事务的状态,包括主事务和分支事务。

事务管理器(Transaction Manager,TM):负责管理事务的生命周期,决定事务何时开始、何时结束,以及提交或回滚事务。TM负责事务的提交和回滚操作。

资源管理器(Resource Manager,RM):监控分支事务的状态并与TC进行数据交互,将分支事务的状态告知TC。

3. 四种分布式事务的解决方案

AT(Auto-Commit):自动提交模式,通过使用数据库的本地事务来实现分布式事务的一致性。

TCC(Try-Confirm-Cancel):尝试-确认-取消模式,通过定义三个阶段的业务方法来实现分布式事务的一致性。

SAGA(Saga):Saga模式是一种长事务解决方案,通过定义一系列补偿操作来实现分布式事务的一致性。

XA(eXtended Architecture):XA模式是一种经典的两阶段提交(2PC)协议,通过协调TM和RM的工作来实现分布式事务的一致性。

对于高并发项目,Seata的AT模式可能不太适用,因为在中间操作时可能会有锁的存在,从而导致效率降低。在选择Seata的解决方案时,可以根据具体的业务场景和性能需求来进行选择。

二、Seata安装

1. 拉取docker镜像

docker pull seataio/seata-server:1.3.0

在这里插入图片描述

2. 拷贝配置文件

docker run -d --name seata -p 8091:8091 seataio/seata-server:1.3.0

在这里插入图片描述

2.1 创建目录

创建/usr/local/docker/seata目录

docker cp seata:/seata-server /usr/local/docker/seata

在这里插入图片描述

2.2 保存file.conf文件

在/usr/local/docker/seata/seata-server/resources文件夹下找到file.conf
将file改成db
在这里插入图片描述
更改数据库连接属性
在这里插入图片描述

3. 启动nacos

docker start nacos

在这里插入图片描述
创建命名空间,找到id:05c721d3-1298-4204-832d-60b94a84cbbd
在这里插入图片描述

4. 保存registry.conf文件

group无需更改,最好不要改
namespace写刚刚拿到的命名空间ID
在这里插入图片描述
在这里插入图片描述

5. 创建config.txt文件

文件内容

#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html
#Transport configuration, for client and server
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
transport.serialization=seata
transport.compressor=none

#Transaction routing rules configuration, only for the client
# ---------------------------------------------------
service.vgroupMapping.my_tx_group=default
# ---------------------------------------------------
#If you use a registry, you can ignore it
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false

#Transaction rule configuration, only for the client
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h

#Log rule configuration, for client and server
log.exceptionRate=100

#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
# ---------------------------------------------------
store.mode=db
store.lock.mode=db
store.session.mode=db
# ---------------------------------------------------
#Used for password encryption
store.publicKey=

#If `store.mode,store.lock.mode,store.session.mode` are not equal to `file`, you can remove the configuration block.
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100

#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
store.db.datasource=druid
store.db.dbType=mysql
# ---------------------------------------------------
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://192.168.43.8:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=123456
# ---------------------------------------------------
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

#These configurations are required if the `store mode` is `redis`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `redis`, you can remove the configuration block.
store.redis.mode=single
store.redis.single.host=127.0.0.1
store.redis.single.port=6379
store.redis.sentinel.masterName=
store.redis.sentinel.sentinelHosts=
store.redis.maxConn=10
store.redis.minConn=1
store.redis.maxTotal=100
store.redis.database=0
store.redis.password=
store.redis.queryLimit=100

#Transaction rule configuration, only for the server
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false

#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

需更改注释之间的数据库连接属性
在这里插入图片描述

6. 创建nacos-config.sh文件

#!/bin/sh
# Copyright 1999-2019 Seata.io Group.
#
# Licensed 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.

while getopts ":h:p:g:t:u:w:" opt
do
  case $opt in
  h)
    host=$OPTARG
    ;;
  p)
    port=$OPTARG
    ;;
  g)
    group=$OPTARG
    ;;
  t)
    tenant=$OPTARG
    ;;
  u)
    username=$OPTARG
    ;;
  w)
    password=$OPTARG
    ;;
  ?)
    echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
    exit 1
    ;;
  esac
done

if [ -z ${host} ]; then
    host=localhost
fi
if [ -z ${port} ]; then
    port=8848
fi
if [ -z ${group} ]; then
    group="SEATA_GROUP"
fi
if [ -z ${tenant} ]; then
    tenant=""
fi
if [ -z ${username} ]; then
    username=""
fi
if [ -z ${password} ]; then
    password=""
fi

nacosAddr=$host:$port
contentType="content-type:application/json;charset=UTF-8"

echo "set nacosAddr=$nacosAddr"
echo "set group=$group"

urlencode() {
  length="${#1}"
  i=0
  while [ $length -gt $i ]; do
    char="${1:$i:1}"
    case $char in
    [a-zA-Z0-9.~_-]) printf $char ;;
    *) printf '%%%02X' "'$char" ;;
    esac
    i=`expr $i + 1`
  done
}

failCount=0
tempLog=$(mktemp -u)
function addConfig() {
  dataId=`urlencode $1`
  content=`urlencode $2`
  curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$dataId&group=$group&content=$content&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
  if [ -z $(cat "${tempLog}") ]; then
    echo " Please check the cluster status. "
    exit 1
  fi
  if [ "$(cat "${tempLog}")" == "true" ]; then
    echo "Set $1=$2 successfully "
  else
    echo "Set $1=$2 failure "
    failCount=`expr $failCount + 1`
  fi
}

count=0
COMMENT_START="#"
for line in $(cat $(dirname "$PWD")/config.txt | sed s/[[:space:]]//g); do
    if [[ "$line" =~ ^"${COMMENT_START}".*  ]]; then
      continue
    fi
    count=`expr $count + 1`
	  key=${line%%=*}
    value=${line#*=}
	  addConfig "${key}" "${value}"
done

echo "========================================================================="
echo " Complete initialization parameters,  total-count:$count ,  failure-count:$failCount "
echo "========================================================================="

if [ ${failCount} -eq 0 ]; then
	echo " Init nacos config finished, please start seata-server. "
else
	echo " init nacos config fail. "
fi

7. 导入nacos配置

首先准备
file.conf、
registry.conf、
config.txt、
nacos-config.sh
以上四个文件备份到桌面,运行如下文件清除seata-server及其下所有文件

cd /usr/local/docker/seata
rm -rf seata-server

在seata文件夹下创建
在这里插入图片描述
在nacos文件夹里放入nacos-config.sh

cd /usr/local/docker/seata/nacos
chmod +x nacos-config.sh
ll

变成绿色为操作成功
在这里插入图片描述

sh nacos-config.sh -h 192.168.43.143 -p 8848 -g SEATA_GROUP -t 05c721d3-1298-4204-832d-60b94a84cbbd -u nacos -w nacos

在这里插入图片描述
会出现上图的错误,运行如下语句就能正常运行

sed -i 's/\r//' nacos-config.sh
sh nacos-config.sh -h 192.168.43.143 -p 8848 -g SEATA_GROUP -t 05c721d3-1298-4204-832d-60b94a84cbbd -u nacos -w nacos

在这里插入图片描述
删除seata下的所有文件(就俩文件,手动删更快)
在这里插入图片描述

8. 复制配置文件

创建config文件夹
将file.conf和registry.conf复制到config文件夹下
运行如下授权语句

cd /usr/local/docker/seata
chmod 777 config

在这里插入图片描述

9. 关闭并删除之前的seata容器

docker stop seata
docker rm seata

在这里插入图片描述

10. 开启mysql容器

docker start mm

在这里插入图片描述
在这里插入图片描述

11. 测试并创建连接

在这里插入图片描述

11. 创建seata数据库

在这里插入图片描述

12. 创建表

DROP TABLE
IF
	EXISTS `global_table`;
CREATE TABLE `global_table` (
	`xid` VARCHAR ( 128 ) NOT NULL,
	`transaction_id` BIGINT,
	`status` TINYINT NOT NULL,
	`application_id` VARCHAR ( 32 ),
	`transaction_service_group` VARCHAR ( 32 ),
	`transaction_name` VARCHAR ( 64 ),
	`timeout` INT,
	`begin_time` BIGINT,
	`application_data` VARCHAR ( 2000 ),
	`gmt_create` datetime,
	`gmt_modified` datetime,
	PRIMARY KEY ( `xid` ),
	KEY `idx_gmt_modified_status` ( `gmt_modified`, `status` ),
	KEY `idx_transaction_id` ( `transaction_id` ) 
);
DROP TABLE
IF
	EXISTS `branch_table`;
CREATE TABLE `branch_table` (
	`branch_id` BIGINT NOT NULL,
	`xid` VARCHAR ( 128 ) NOT NULL,
	`transaction_id` BIGINT,
	`resource_group_id` VARCHAR ( 32 ),
	`resource_id` VARCHAR ( 256 ),
	`lock_key` VARCHAR ( 128 ),
	`branch_type` VARCHAR ( 8 ),
	`status` TINYINT,
	`client_id` VARCHAR ( 64 ),
	`application_data` VARCHAR ( 2000 ),
	`gmt_create` datetime,
	`gmt_modified` datetime,
	PRIMARY KEY ( `branch_id` ),
	KEY `idx_xid` ( `xid` ) 
);
DROP TABLE
IF
	EXISTS `lock_table`;
CREATE TABLE `lock_table` (
	`row_key` VARCHAR ( 128 ) NOT NULL,
	`xid` VARCHAR ( 96 ),
	`transaction_id` LONG,
	`branch_id` LONG,
	`resource_id` VARCHAR ( 256 ),
	`table_name` VARCHAR ( 100 ),
	`pk` VARCHAR ( 36 ),
	`gmt_create` datetime,
	`gmt_modified` datetime,
	PRIMARY KEY ( `row_key` ) 
);

创建语句如上

13. 启动seata

docker run --name seata \
-p 8091:8091 \
-e SEATA_IP=192.168.43.143 \
-e SEATA_PORT=8091 \
-e SEATA_CONFIG_NAME=file:/root/seata-config/registry \
-v /usr/local/docker/seata/config:/root/seata-config  \
-d seataio/seata-server:1.3.0

在这里插入图片描述
运行如下语句看到8091即为成功

docker logs -f seata

在这里插入图片描述

三、普通事务回滚

1. 项目基础

一些基础的项目结构无需我们编写,以提供
通过网盘分享的文件:241005_seata.zip
链接: https://pan.baidu.com/s/1xTs4uV-3VAiRCPzBjd-Qow?pwd=k25m 提取码: k25m
以下所有操作都会在两个项目同时进行,如果是单个项目进行的会额外标出
以下所有操作都会在两个项目同时进行,如果是单个项目进行的会额外标出
以下所有操作都会在两个项目同时进行,如果是单个项目进行的会额外标出

2. 更改application.yml内数据库连接属性

在这里插入图片描述

3. 创建score数据库

在这里插入图片描述
在这里插入图片描述
创建score数据库和user数据库
score数据库里有score表和undo_log表
user数据库里有user表和undo_log表,两者的undo_log表相同
表结构如下:

CREATE TABLE `score`  (
  `id` varchar(50)  NOT NULL,
  `name` varchar(50)  NULL,
  `score` double(7, 2) NULL ,
  PRIMARY KEY (`id`) USING BTREE
) 

CREATE TABLE `user`  (
  `id` varchar(50)  NOT NULL,
  `name` varchar(50)  NULL,
  `password` varchar(50)  NULL,
  PRIMARY KEY (`id`) USING BTREE
) 
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;

4. 运行项目

4.1 正常运行

在这里插入图片描述
在这里插入图片描述

4.2 异常运行测试回滚

项目1内 添加异常语句,测试回滚
在这里插入图片描述
重启项目
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
出错了,但是发现数据库内两个都添加成功了

5. 添加普通的事务回滚

在两个项目的UserServiceImpl/ScoreServiceImpl中添加注解

    @GlobalTransactional(rollbackFor = Exception.class)

再次启动项目
user的post出错添加失败
在这里插入图片描述
但是score的请求成功了
在这里插入图片描述
事务没有实现原子性
如何解决呢

四、Seata事务回滚

依旧是两个项目同时添加

1. 添加依赖

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

2. 启动类添加注释

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

3. 修改application.yml配置文件

修改为如下格式

server:
  port: 100

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.43.143:3306/user
    username: root
    password: 123456

mybatis:
  mapper-locations: classpath:com/jr/mapper/*.xml
  type-aliases-package: com.jr.entry

seata:
  application-id: ${spring.application.name}
  enabled: true
  tx-service-group: my_tx_group
  registry:
    type: nacos
    nacos:
      server-addr: 192.168.43.143:8848
      namespace: 05c721d3-1298-4204-832d-60b94a84cbbd
      group: SEATA_GROUP
      username: nacos
      password: nacos
  config:
    type: nacos
    nacos:
      server-addr: 192.168.43.143:8848
      namespace: 05c721d3-1298-4204-832d-60b94a84cbbd
      group: SEATA_GROUP
      username: nacos
      password: nacos
  service:
    vgroup-mapping:
      my_tx_group: default

feign:
  httpclient:
    connection-timeout: 600000
    connection-timer-repeat: 30000

4. 更改事务注解

@GlobalTransactional(rollbackFor = Exception.class,timeoutMills = 300000)

在这里插入图片描述

5. 启动项目

5.1 有错误时

两个都不添加了
在这里插入图片描述
在这里插入图片描述

5.2 无错误时

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
都能请求成功


总结

本文讲述了:
Seata:项目间事务回滚
在下攸攸太上,女朋友超级可爱。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为eNSP:端口隔离

一&#xff0c;什么是端口隔离 端口隔离是一种网络配置技术&#xff0c;用于将不同的网络设备或用户隔离在不同的虚拟局域网&#xff08;VLAN&#xff09;中&#xff0c;以实现网络流量的隔离和安全性提升。通过在交换机或路由器上配置端口隔离&#xff0c;可以将连接到同一设…

【机器学习-无监督学习】概率图模型

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…

在VS code 中部署C#和avalonia开发环境

要在 Mac 的 VS Code 中配置 C# 和 Avalonia 的开发环境&#xff0c;您可以按照以下步骤进行&#xff1a; 1. 安装 .NET SDK 下载 .NET SDK&#xff1a; 访问 .NET 下载页面。选择适用于 macOS 的最新稳定版本的 .NET SDK&#xff0c;并下载安装程序。安装 .NET SDK&#xff1…

VSCode | 设置Jupyter Notebook显示行号

vscode中的jupyter notebook每个cell都是默认不显示行号的&#xff0c;如果出现了报错&#xff0c;比如在52行出现报错&#xff0c;如果代码多的话不显示行号就有点麻烦&#xff0c;本文介绍如何设置显示行号。 1、VScode点击文件-首选项-设置 2、搜索“python”&#xff0c;点…

约数个数约数之和

好久没发文章了.......不过粉丝还是一个没少...... 今天来看两道超级恶心的数论题目&#xff01; No.1 约数个数 No.2 约数之和 先来看第一道&#xff1a;约数个数 题目描述 给定 n 个正整数 ai​,请你输出这些数的乘积的约数个数,答案对 10^97 取模 输入格式 第一行包含…

cherry-markdown开源markdown组件详细使用教程

文章目录 前言开发定位目标调研技术方案前提工作量安排数据库表设计实现步骤1、引入依赖2、实现cherry-markdown的vue组件&#xff08;修改上传接口路径&#xff09;3、支持draw.io组件4、支持展示悬浮目录toc前端使用&#xff1a;编辑状态使用cherry-markdown的vue组件前端使用…

netty之Netty心跳服务与断线重连

前言 使用netty中&#xff0c;需要监测服务是否稳定以及在网络异常链接断开时候可以自动重连。需要实现监听&#xff1b;f.addListener(new MyChannelFutureListener()) 代码目录结构 package com.lm.demo.netty.client;import io.netty.channel.ChannelFuture; import io.nett…

【11】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-模块化语法与自定义组件

序言&#xff1a; 本文详细讲解了关于鸿蒙系统学习中的模块化语法与自定义组件&#xff0c;在模块化语法中我们学习到了多种导入导出方式&#xff0c;实现了在一个项目中&#xff0c;通过引用不同的组件&#xff0c;让我们整体代码的可读性更强&#xff0c;相当于我们把一个手…

认知战认知作战:认知战与安全挑战中方企业在海外的应对策略分析

认知战认知作战&#xff1a;认知战与安全挑战中方企业在海外的应对策略分析 关键词&#xff1a;认知战, 中方企业, 恐怖袭击, 安全挑战, 信息传播, 社会责任, 风险管理, 国际合作,认知作战,新质生产力,人类命运共同体,认知战,认知域,认知战研究中心,认知战争,认知战战术,认知战…

MATLAB中lsqminnorm函数用法

目录 语法 说明 示例 求解具有无限个解的线性系统 指定容差以减少含噪数据的影响 切换显示低秩矩阵警告 lsqminnorm函数的功能是线性方程的最小范数最小二乘解。 语法 X lsqminnorm(A,B) X lsqminnorm(A,B,tol) X lsqminnorm(___,rankWarn) 说明 X lsqminnorm(A,B…

Ansible学习之ansible-pull命令

想要知道ansible-pull是用来做什么的&#xff0c;就需要了解Ansible的工作模&#xff0c;Ansible的工作模式有两种&#xff1a; push模式 push推送&#xff0c;这是Ansible的默认模式&#xff0c;在主控机上编排好playbook文件&#xff0c;push到远程主机上来执行。pull模式 p…

QT系统学习篇(2)- Qt跨平台GUI原理机制

一、Qt工程管理 1、新建项目&#xff1a; 我们程序员新建项目对话框所有5类项目模板 Application: Qt的应用程序&#xff0c;包含Qt Quick和普通窗口程序。 Library: 它可以创建动态库、静态库、Qt Creator自身插件、Qt Quick扩展插件。 其他项目: 创建单元测试项目、子目录项…

数据分析之Spark框架介绍

文章目录 概述一、发展历程与背景二、核心特点三、生态系统与组件四、应用场景五、与其他大数据技术的比较 核心概念1. 弹性分布式数据集&#xff08;RDD, Resilient Distributed Dataset&#xff09;2. 转换&#xff08;Transformations&#xff09;和动作&#xff08;Actions…

Redis主从复制(replica)、哨兵

一、Redis主从复制介绍: 主从复制&#xff0c;master主机以写为主&#xff0c;slave从机以读为主&#xff0c;当主机数据变化的时候自动将新的数据异步同步到其他从机数据库&#xff1b;能够实现读写分离&#xff0c; 容灾恢复、 数据备份以及水平扩容支撑高并发 二、实现方法…

【stm32】ADC的介绍与使用

ADC的介绍与使用 1、ADC介绍2、逐次逼近型ADC3、ADC电路4、ADC基本结构程序代码编写&#xff1a;ADC 通道和引脚复用的关系 5、转换模式&#xff08;1&#xff09;单次转换&#xff0c;非扫描模式转换流程&#xff1a;程序编写&#xff1a; &#xff08;2&#xff09;连续转换&…

基于 springboot vue中学生日常行为评分管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…

​通用代码生成器典型应用场景​

​通用代码生成器典型应用场景​ 1. 通用代码生成器简介 通用代码生成器或称动词算子式通用代码生成器&#xff0c;是一系列各种语言的易用的整站式代码生成器。其根本原理是把方法分解成动词算子和域对象的笛卡儿积。根据动词算子式代码生成器的基本原理。所有方法&#xff…

网 络 安 全

网络安全是指保护网络系统及其所存储或传输的数据免遭未经授权访问、使用、揭露、破坏、修改或破坏的实践和技术措施。网络安全涉及多个方面&#xff0c;包括但不限于以下几个方面&#xff1a; 1. 数据保护&#xff1a;确保数据在传输和存储过程中的完整性和保密性&#xff0c;…

[Python] 《人生重开模拟器》游戏实现

文章目录 优化点一&#xff1a;多元化的天赋系统示例天赋&#xff1a;天赋选择代码&#xff1a; 优化点二&#xff1a;更加多样化的随机事件年龄阶段划分&#xff1a;随机事件代码&#xff1a; 优化点三&#xff1a;设定人生目标人生目标示例&#xff1a;人生目标代码&#xff…

python爬虫 - 初识requests模块

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 前言 requests 是一个用于发送 HTTP 请求的 Python 库&#xff0c;设计简单且功能强大&am…