探索 Seata 分布式事务

news2024/11/14 17:11:53

Seata(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源的一款分布式事务解决方案,旨在帮助开发者解决微服务架构下的分布式事务问题。它提供了高效且易于使用的分布式事务管理能力,支持多种事务模式,确保数据的一致性和完整性。

以下是 Seata 的一些关键特性和功能:

  1. 全局事务管理:Seata 提供了一个全局事务协调器(Transaction Coordinator, TC),负责管理全局事务的生命周期,包括开始、提交、回滚等操作。

  2. AT 模式(Automatic Transaction):这是 Seata 最常用的事务模式,通过代理数据库操作,实现自动的分支事务管理。AT 模式下,Seata 会在业务操作前后自动生成快照,并在事务提交或回滚时进行相应的处理。

  3. TCC 模式(Try-Confirm-Cancel):这种模式需要开发者手动实现 Try、Confirm 和 Cancel 三个阶段的逻辑。Try 阶段预留资源,Confirm 阶段确认操作,Cancel 阶段则回滚操作。这种模式适用于需要精细控制事务逻辑的场景。

  4. SAGA 模式:基于补偿机制的长事务解决方案,适用于跨多个服务的复杂业务流程。每个步骤都有对应的补偿操作,当某一步失败时,可以通过执行补偿操作来回滚整个事务。

  5. XA 模式:基于两阶段提交协议的分布式事务解决方案,适用于支持 XA 协议的数据库。第一阶段准备事务,第二阶段提交或回滚事务。

  6. 高性能:Seata 通过优化网络通信和存储机制,提供了高性能的事务处理能力,能够满足大规模分布式系统的需求。

  7. 易于集成:Seata 支持与 Spring Cloud、Dubbo、gRPC 等主流微服务框架的无缝集成,开发者只需进行简单配置即可使用分布式事务功能。

  8. 可扩展性:Seata 提供了丰富的 SPI 接口,允许开发者根据具体需求进行扩展和定制,例如自定义事务日志存储、事务协调策略等。

  9. 社区活跃:作为一个开源项目,Seata 拥有活跃的社区和丰富的文档资源,开发者可以方便地获取支持和帮助。

通过 Seata,开发者可以轻松地在分布式系统中实现一致性事务管理,确保数据的一致性和完整性,从而提高系统的可靠性和稳定性。

参考 官方文档

下载 Seata

官方下载地址

 我使用的是 1.4.1 版本:

进入conf目录,调整下面的配置文件

registry.conf

设置使用 Nacos 注册中心:

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  # type = "file"
  type = "nacos"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  nacos {
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    group = "SEATA_GROUP"
    namespace = "public"
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  # type = "file"
  type = "nacos"
  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = "public"
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
  }

}

file.conf

使用 MySQL 8.X JDBC 驱动、数据库账号、密码:

## transaction log store, only used in seata-server
store {
  ## store mode: file、db、redis
  mode = "db"

  ## file store property
  file {
    ## store location dir
    dir = "sessionStore"
    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    maxBranchSessionSize = 16384
    # globe session size , if exceeded throws exceptions
    maxGlobalSessionSize = 512
    # file buffer size , if exceeded allocate new buffer
    fileWriteBufferCacheSize = 16384
    # when recover batch read size
    sessionReloadReadSize = 100
    # async, sync
    flushDiskMode = async
  }

  ## database store property
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.cj.jdbc.Driver"
    url = "jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true"
    user = "root"
    password = "root"
    minConn = 5
    maxConn = 100
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }

  ## redis store property
  redis {
    host = "127.0.0.1"
    port = "6379"
    password = ""
    database = "0"
    minConn = 1
    maxConn = 10
    maxTotal = 100
    queryLimit = 100
  }

}

seata-1.4.1 配置

克隆 1.4.1 分支

git clone -b 1.4.1 https://gitee.com/ma-jiansheng/seata

微服务 yml 配置

seata:
  enabled: true
  application-id: admin-server
  tx-service-group: admin-server-group
  enable-auto-data-source-proxy: true
  config:
    type: nacos
    nacos:
      namespace: public
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      userName: "nacos"
      password: "nacos"
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      namespace: public
      userName: "nacos"
      password: "nacos"

修改 script/config-center 下 config.txt 文件

修改 service.vgroupMapping 和数据库地址:

transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
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
service.vgroupMapping.my_test_tx_group=default
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
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=false
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
service.vgroupMapping.admin-server-group=default
service.vgroupMapping.discussion-server-group=default
service.vgroupMapping.enterprise-server-group=default
service.vgroupMapping.job-server-group=default
service.vgroupMapping.student-server-group=default
store.mode=db
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
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql:///dgut?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
store.db.user=root
store.db.password=root
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
store.redis.host=127.0.0.1
store.redis.port=6379
store.redis.maxConn=10
store.redis.minConn=1
store.redis.database=0
store.redis.password=null
store.redis.queryLimit=100
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
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
log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

 注意:

service.vgroupMapping.admin-server-group=default
service.vgroupMapping.discussion-server-group=default
service.vgroupMapping.enterprise-server-group=default
service.vgroupMapping.job-server-group=default
service.vgroupMapping.student-server-group=default

ABC-server-group 与项目模块中 yml 配置的 seata.tx-service-group 内容相同。

启动 nacos-config.sh ,将配置注入到 nacos 中

sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -u nacos -w nacos

 在 nocos 中心可以看到新增的配置:

 启动 Seata 服务

seata-server.bat -p 9000 -m file

-p 指定启动seata server的端口号。
-h 指定seata server所绑定的主机。
-m 事务日志、事务执行信息存储的方式,目前支持file(文件方式)、db(数据库方式,建表语句请查看config/db_store.sql、config/db_undo_log.sql)

报错:

原因:路径问题,需手动指定 logs 路径 

修改启动脚本:

@REM ----------------------------------------------------------------------------
@REM  Copyright 2001-2006 The Apache Software Foundation.
@REM
@REM  Licensed under the Apache License, Version 2.0 (the "License");
@REM  you may not use this file except in compliance with the License.
@REM  You may obtain a copy of the License at
@REM
@REM       http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM  Unless required by applicable law or agreed to in writing, software
@REM  distributed under the License is distributed on an "AS IS" BASIS,
@REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@REM  See the License for the specific language governing permissions and
@REM  limitations under the License.
@REM ----------------------------------------------------------------------------
@REM
@REM   Copyright (c) 2001-2006 The Apache Software Foundation.  All rights
@REM   reserved.

@echo off

set ERROR_CODE=0

:init
@REM Decide how to startup depending on the version of windows

@REM -- Win98ME
if NOT "%OS%"=="Windows_NT" goto Win9xArg

@REM set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" @setlocal

@REM -- 4NT shell
if "%eval[2+2]" == "4" goto 4NTArgs

@REM -- Regular WinNT shell
set CMD_LINE_ARGS=%*
goto WinNTGetScriptDir

@REM The 4NT Shell from jp software
:4NTArgs
set CMD_LINE_ARGS=%$
goto WinNTGetScriptDir

:Win9xArg
@REM Slurp the command line arguments.  This loop allows for an unlimited number
@REM of arguments (up to the command line limit, anyway).
set CMD_LINE_ARGS=
:Win9xApp
if %1a==a goto Win9xGetScriptDir
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto Win9xApp

:Win9xGetScriptDir
set SAVEDIR=%CD%
%0\
cd %0\..\.. 
set BASEDIR=%CD%
cd %SAVEDIR%
set SAVE_DIR=
goto repoSetup

:WinNTGetScriptDir
set BASEDIR=%~dp0\..

:repoSetup
set REPO=


if "%JAVACMD%"=="" set JAVACMD=java

if "%REPO%"=="" set REPO=%BASEDIR%\lib

set CLASSPATH="%BASEDIR%"\conf;"%REPO%"\*

set ENDORSED_DIR=
if NOT "%ENDORSED_DIR%" == "" set CLASSPATH="%BASEDIR%"\%ENDORSED_DIR%\*;%CLASSPATH%

if NOT "%CLASSPATH_PREFIX%" == "" set CLASSPATH=%CLASSPATH_PREFIX%;%CLASSPATH%

@REM Reaching here means variables are defined and arguments have been captured
:endInit

%JAVACMD% %JAVA_OPTS% -server -Xmx512m -Xms512m -Xmn512m -Xss512k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\ideaFiles\seata-server-1.4.1\seata\bin\logs\java_heapdump.hprof -XX:+DisableExplicitGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -Xloggc:D:\ideaFiles\seata-server-1.4.1\seata\bin\logs\seata_gc.log -verbose:gc -Dio.netty.leakDetectionLevel=advanced -Dlogback.color.disable-for-bat=true -classpath %CLASSPATH% -Dapp.name="seata-server" -Dapp.repo="%REPO%" -Dapp.home="%BASEDIR%" -Dbasedir="%BASEDIR%" io.seata.server.Server %CMD_LINE_ARGS%
if %ERRORLEVEL% NEQ 0 goto error
goto end

:error
if "%OS%"=="Windows_NT" @endlocal
set ERROR_CODE=%ERRORLEVEL%

:end
@REM set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" goto endNT

@REM For old DOS remove the set variables from ENV - we assume they were not set
@REM before we started - at least we don't leave any baggage around
set CMD_LINE_ARGS=
goto postExec

:endNT
@REM If error code is set to 1 then the endlocal was done already in :error.
if %ERROR_CODE% EQU 0 @endlocal


:postExec

if "%FORCE_EXIT_ON_ERROR%" == "on" (
  if %ERROR_CODE% NEQ 0 exit %ERROR_CODE%
)

exit /B %ERROR_CODE%

再次启动:成功

nacos 注册中心可以查看到 Seata 服务已启动:

使用 Seata 实现事务控制

创建数据库seata

建立下面三张表(branch_table, global_table, lock_table):

-- the table to store GlobalSession data
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(128),
  `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`)
);

-- the table to store BranchSession data
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`)
);

-- the table to store lock data
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(32) ,
  `pk` varchar(36) ,
  `gmt_create` datetime ,
  `gmt_modified` datetime,
  primary key(`row_key`)
);

在 dgut 数据库中加入一张 undo_log 表

这是 Seata 记录事务日志要用到的表:

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;

添加配置

在需要进行分布式控制的微服务中进行下面几项配置:

pom依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <!-- 里面已经集成服务间调用X-id的传递,包括FeignClient的重写,如果在之前自定义封装过Feign,注意启动冲突-->
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <exclusions>
        <!--去除低版本-->
        <exclusion>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- 添加 seata starter ,与服务端保持一致-->
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.4.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

添加配置类 DataSourceProxyConfig

package com.yushanma.config;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class DataSourceProxyConfig {
@Bean
    @ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
    }
@Primary
    @Bean
    public DataSourceProxy dataSource(DruidDataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
    }
}

yml 配置加入 Seata

seata:
enabled: true
  application-id: order-server
tx-service-group: order-server-group
enable-auto-data-source-proxy: true
  config:
type: nacos
    nacos:
namespace: public
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
userName: "nacos"
      password: "nacos"
  registry:
type: nacos
    nacos:
application: seata-server
server-addr: 127.0.0.1:8848
namespace: public
userName: "nacos"
      password: "nacos"

微服务开启全局事务 @GlobalTransactional

 测试

在插入语句和异常语句设置断点:

此时,未执行插入语句,undo_log 为空:

断点往下走,此时数据库执行插入语句,但未抛出异常,undo_log 有记录:

断点往下走,0 为分母抛出异常,控制台报错:

可以看到 Seata 控制台也有相关信息:

此时执行了事务回滚,undo_log 为空:

数据插入失败,则 dgut_school_admin 表无新增记录:

可见,Seata 事务有效。

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

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

相关文章

AI写作(七)的核心技术探秘:情感分析与观点挖掘

一、AI 写作中的关键技术概述 情感分析与观点挖掘在 AI 写作中起着至关重要的作用。情感分析能够帮助 AI 理解文本中的情感倾向&#xff0c;无论是正面、负面还是中性。在当今信息时代&#xff0c;准确把握用户情绪对于提供个性化体验和做出明智决策至关重要。例如&#xff0c;…

容器化技术入门:Docker详解

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 容器化技术入门&#xff1a;Docker详解 容器化技术入门&#xff1a;Docker详解 容器化技术入门&#xff1a;Docker详解 引言 Doc…

Flutter运行App时出现“Running Gradle task ‘assembleDebug“问题解决

在参考了众多解决办法中最有用并且最快的方法 Gradle Distributions 在这个地方下载对应你这个文件中的gradle版本 然后将 最后一行本来不是这样的,我们把下载好的zip包保存到本地,然后用这个代替网址,最后成功运行

Spark中的shuffle

Shuffle的本质基于磁盘划分来解决分布式大数据量的全局分组、全局排序、重新分区【增大】的问题。 1、Spark的Shuffle设计 Spark Shuffle过程也叫作宽依赖过程&#xff0c;Spark不完全依赖于内存计算&#xff0c;面临以上问题时&#xff0c;也需要Shuffle过程。 2、Spark中哪…

window11安装elasticsearch+Kibana

1、下载elasticsearch与elasticsearch 下载elasticsearch 查看elasticsearch对应的Kibana版本 下载elasticsearch解压后文件目录如下 可执行脚本文件,包括启动elasticsearch服务、插件管理、函数命令等 bin配置文件目录,如elasticsearch配置、角色配置、jvm配置等 conf 默认…

linux rocky 9.4部署和管理docker harbor私有源

文章目录 Harbor简介安装Harbor技术细节1.安装系统(略),设置主机名和IP2.安装docker3.安装docker-compose4.安装Harbor私有源仓库5 测试登录1.本机登录2.客户端登录Harbor服务器配置docker源1. 下载镜像2.把镜像上传到Harbor私有仓库源3.客户端下载镜像,并且启动容器linux …

【计算机网络五】HTTP协议!网站运行的奥秘!

目录 HTTP协议 1.HTTP是什么&#xff1f; 2.Fiddler抓包查看HTTP协议格式 3.HTTP请求 4.HTTP响应 HTTP协议 1.HTTP是什么&#xff1f; HTTP ( 全称为 " 超文本传输协议 ") 诞生与 1991 年 . 目前已经发展为最主流使用的一种应用层协议 . HTTP 的前几个版本…

嵌入式硬件实战基础篇(一)-STM32+DAC0832 可调信号发生器-产生方波-三角波-正弦波

引言&#xff1a;本内容主要用作于学习巩固嵌入式硬件内容知识&#xff0c;用于想提升下述能力&#xff0c;针对学习STM32与DAC0832产生波形以及波形转换&#xff0c;对于硬件的降压和对于前面硬件篇的实际运用&#xff0c;针对仿真的使用&#xff0c;具体如下&#xff1a; 设…

ubuntu 24.04运行chattts时cuda安装错误原因分析

使用ubuntu 24.04&#xff0c;按照2noise/ChatTTS官方流程安装依赖时报错。ChatTTShttps://github.com/2noise/ChatTTS 这是因为cuda版本不对&#xff0c;ChatTTS目前的版本&#xff0c;要求支持cuda 12.4及以上&#xff0c;但是如果nvidia显卡驱动版本较老&#xff0c;无法支…

【动态规划】斐波那契数列模型总结

一、第 N 个泰波那契数 题目链接&#xff1a; 第 N 个泰波那契数 题目描述&#xff1a; 题目分析&#xff1a; 1、状态表示&#xff1a; dp[i] 表示&#xff1a;第 i 个斐波那契数的值 2、状态转移方程&#xff1a; 由题意可知第 i 个数等于其前三个数之和 dp[i] dp[i-…

2024 第五次周赛

A: 直接遍历即可 #include<bits/stdc.h> using namespace std;typedef long long ll; typedef pair<ll, ll>PII; const int N 2e6 10; const int MOD 998244353; const int INF 0X3F3F3F3F;int n, m; int main() {cin >> n;int cnt 0;for(int i 0; i …

【数据库系列】postgresql链接详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Uniapp底部导航栏设置(附带PS填充图标教程)

首先需要注册和登录ifconfont官网&#xff0c;然后创建项目添加需要的图标 创建和添加图标库请参考&#xff1a;Uniapp在Vue环境中引入iconfont图标库&#xff08;详细教程&#xff09; 打开iconfont官网&#xff0c;找到之前添加的图标库&#xff0c;下载png图片 如果需要的…

提取神经网络数学表达式

来自《老饼讲解神经网络》 www..bbbdata.com 当我们在matlab训练好网络后&#xff0c;可以使用神经网络工具箱的sim(net,x)函数进行预测输出。但往往想提取出它的数学表达式&#xff0c;该怎么提取呢&#xff1f; 下面以《一个简单的神经网络例子》中的模型为例&#xff0c;提取…

【从零开始鸿蒙开发:01】自定义闪屏页

文章目录 大体介绍文件介绍各部分代码SplashPage.etsIndex.etsHomePage.etsroute_map.jsonmodule.json5 流程 大体介绍 文件介绍 其中&#xff1a; pages为我们的页面内容&#xff08;我个人理解功能性小于activity但是大于fragment&#xff09;route_map.json 为自定义的路由…

录制的音频听起来非常缓慢,声音很模糊

一、主题 录制的音频听起来非常缓慢&#xff0c;声音很模糊 二、问题背景 硬件&#xff1a;T113&#xff0c;R528等平台系列产品 软件&#xff1a;Tina5.0 三、问题描述 1、复现步骤 使用arecord进行录音。 arecord -Dhw:audiocodec -f S16_LE -r 16000 -c 2 -d 5 /tmp/t…

Android笔记(三十五):用责任链模式封装一个App首页Dialog管理工具

背景 项目需要在首页弹一系列弹窗&#xff0c;每个弹窗是否弹出都有自己的策略&#xff0c;以及哪个优先弹出&#xff0c;哪个在上一个关闭后再弹出&#xff0c;为了更好管理&#xff0c;于是封装了一个Dialog管理工具 效果 整体采用责任链模块设计&#xff0c;控制优先级及弹…

[CKS] K8S Dockerfile和yaml文件安全检测

最近准备花一周的时间准备CKS考试&#xff0c;在准备考试中发现有一个题目关于Dockerfile和yaml文件安全检测的题目。 ​ 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博…

Golang | Leetcode Golang题解之第552题学生出勤记录II

题目&#xff1a; 题解&#xff1a; const mod int 1e9 7type matrix [6][6]intfunc (a matrix) mul(b matrix) matrix {c : matrix{}for i, row : range a {for j : range b[0] {for k, v : range row {c[i][j] (c[i][j] v*b[k][j]) % mod}}}return c }func (a matrix) p…

(Go语言)初上手Go?本篇文章帮拿捏Go的数据类型!

1. bool 类型 布尔类型&#xff1a;只有 true 和 false 两种值 在Go中&#xff0c;整数 0 不代表 false 值&#xff0c;1也不代表 true 值 即数字无法代替布尔值进行逻辑判断&#xff0c;两者是完全不同的类型 布尔类型占用 1 字节 2. int 整型 Go中为不同位数的整数分配…