Seata搭建
1.初识Seata
Quick Start | Apache Seata 官网
2.准备nacos和 seata
启动nacos
startup.cmd -m standalone
账号nacos 密码nacos
搭建seata TC
这里下载的 1.4.2
seata-server-1.4.2
1.修改seata配置文件
registry.conf
这里我们使用nacos作为注册中心 和 配置中心
registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa# 注册中心 nacostype = "nacos"# 注册中心的配置nacos {application = "seata-tc-server"serverAddr = "127.0.0.1:8848"group = "DEFAULT_GROUP"namespace = ""cluster = "default"username = "nacos"password = "nacos"}}# 配置文件
config {# file、nacos 、apollo、zk、consul、etcd3type = "nacos" #还是放nacos上面nacos {serverAddr = "127.0.0.1:8848"namespace = ""group = "SEATA_GROUP"username = "nacos"password = "nacos"dataId = "seataServer.properties"}}
store.mode=db
#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.jdbc.Driver
store.db.url=jdbc:mysql://192.168.181.202:3306/seata?useUnicode=true&rewriteBatchedStatements=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.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000#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.rollbackFailedUnlockEnable=false
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none# 关闭metrics功能,提高性能
#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
2.创建数据库 创建表
建表SQL
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `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_status_gmt_modified` (`status` , `gmt_modified`),KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(`branch_id` BIGINT NOT NULL,`xid` VARCHAR(128) NOT NULL,`transaction_id` BIGINT,`resource_group_id` VARCHAR(32),`resource_id` VARCHAR(256),`branch_type` VARCHAR(8),`status` TINYINT,`client_id` VARCHAR(64),`application_data` VARCHAR(2000),`gmt_create` DATETIME(6),`gmt_modified` DATETIME(6),PRIMARY KEY (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(`row_key` VARCHAR(128) NOT NULL,`xid` VARCHAR(128),`transaction_id` BIGINT,`branch_id` BIGINT NOT NULL,`resource_id` VARCHAR(256),`table_name` VARCHAR(32),`pk` VARCHAR(36),`status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',`gmt_create` DATETIME,`gmt_modified` DATETIME,PRIMARY KEY (`row_key`),KEY `idx_status` (`status`),KEY `idx_branch_id` (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;CREATE TABLE IF NOT EXISTS `distributed_lock`
(`lock_key` CHAR(20) NOT NULL,`lock_value` VARCHAR(20) NOT NULL,`expire` BIGINT,primary key (`lock_key`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);
3.运行
cmd 运行
seata-server.bat
win bat
mac sh
什么参数不加就是默认配置 默认端口 默认信息
nacos 注册完成
3.微服务集成Seata
比如在 pro 商品服务导入依赖
1.导入依赖
这时老版本 2.9.9 realease springboot版本 使用的 版本
<!--分布式事务--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><!--版本较低 1.3.0 因此排除--><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions></dependency><!--seata starter 采用 1.4.2版本--><dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.4.2</version></dependency>
因为自动装配,所以只需告诉服务 TC 服务的地址 在哪里
参考官网
2.yml配置
seata:registry: #TC服务注册中心的配置,微服务根据这些信息取注册中心获取tc服务地址#参考tc服务自己的 registry.conf 中的配置,#包括:地址 namespace, group,application-name, clustertype: nacosnacos: #TCserver-addr: 127.0.0.1:8848group: DEFAULT_GROUPnamespace: "" #因为都在public 所以用空串application: seata-tc-serverusername: "nacos"password: "nacos"tx-service-group: seata-demo #事务组,根据这个获取tc服务的cluster名称 自己取的名称#把事务做分组 订单服务商品服务 它们是一个事务 想被同一个集群管理,它们就可以设置为同一个事务组#方便将来做快速失败 集群容错的 管理service:vgroup-mapping: #事务组与TC服务cluster的映射关系 事务组怎么找到我的集群名称呢,那么将映射到default这个集群当中seata-demo: default #没有集群默认是 default nacos里 seata-demo 映射 到 default
重启
把需要做分布式事务的服务都做一遍配置
重启
4.实现分布式事务
1.XA模式
基于数据库实现的 Mysql支持 XA 先让一个不提交 等所有都没有问题 然后同时提交
失败一个回滚所有,它是基于数据库本身的实现,来阻塞提交,性能不好
1.Seata的实现
优势
强一致性
缺点
可用性降低了
2.代码实现
在每个需要全局事务管理的服务加上
seata:registry: #TC服务注册中心的配置,微服务根据这些信息取注册中心获取tc服务地址#参考tc服务自己的 registry.conf 中的配置,#包括:地址 namespace, group,application-name, clustertype: nacosnacos: #TCserver-addr: 127.0.0.1:8848group: DEFAULT_GROUPnamespace: "" #因为都在public 所以用空串application: seata-tc-serverusername: "nacos"password: "nacos"tx-service-group: seata-demo #事务组,根据这个获取tc服务的cluster名称 自己取的名称#把事务做分组 订单服务商品服务 它们是一个事务 想被同一个集群管理,它们就可以设置为同一个事务组#方便将来做快速失败 集群容错的 管理service:vgroup-mapping: #事务组与TC服务cluster的映射关系 事务组怎么找到我的集群名称呢,那么将映射到default这个集群当中seata-demo: default #没有集群默认是 default nacos里 seata-demo 映射 到 defaultdata-source-proxy-mode: XA #开启数据源代理的XA模式
加上GlobalTransaction注解
@GetMapping("/add")@GlobalTransactional(rollbackFor = Exception.class)public R addDingdan(@RequestParam("order") String order) {SpuInfoEntity spuInfoEntity = new SpuInfoEntity();spuInfoEntity.setSpuName(order);spuInfoService.save(spuInfoEntity);CouponHistoryEntity couponHistoryEntity = new CouponHistoryEntity();couponHistoryEntity.setMemberNickName(order);couponFeignService.saveTrySeata(couponHistoryEntity);return R.ok();}
另一个服务 也一定要加事务要不然会造成死锁
@RequestMapping("/save")@Transactional(rollbackFor = Exception.class)public R save(@RequestBody CouponHistoryEntity couponHistory) throws Exception {couponHistoryService.save(couponHistory);CouponHistoryEntity couponHistory1 = new CouponHistoryEntity();BeanUtils.copyProperties(couponHistory,couponHistory1);couponHistory1.setId(1011L);couponHistoryService.save(couponHistory1);CouponHistoryEntity couponHistory2 = new CouponHistoryEntity();BeanUtils.copyProperties(couponHistory,couponHistory2);couponHistory2.setId(1012L);couponHistoryService.save(couponHistory2);CouponHistoryEntity couponHistory3 = new CouponHistoryEntity();BeanUtils.copyProperties(couponHistory,couponHistory3);couponHistory3.setId(1013L);couponHistoryService.save(couponHistory3);return R.ok();}
2.AT模式
1.AT模式原理
2.AT模式的脏写问题
全局锁的机制
3. 代码实现
上面一开始就导入了 lock_table 到 seata服务器所在的数据库
然后只需要导入 undo_log 表就可以了 每个用到分布式事务的微服务所在的数据库都必须要导入一张undo_log表
CREATE TABLE IF NOT EXISTS `undo_log`
(`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
seata:data-source-proxy-mode: AT
重启一下就完事了,无代码侵入
测试回滚成功,和上面XA一样的代码不用动
3.TCC模式
1.TCC模式原理
2.TCC代码实现
1.先建一张 冻结表
CREATE table `pms_spu_info_tbl`( `xid` varchar(128) NOT NULL,`user_id` varchar(255) Default null comment '用户ID',`freeze_money` int unsigned default '0' comment '冻结金额',`state` int default null comment '事务状态,0:try,1:confirm,2:cancel',Primary key (`xid`) USING BTREE
) ENGINE = InnoDB Default charset=utf8;
2.try业务
记录冻结金额和事务状态到 pms_spu_info_tbl
添加金额
3.confirm业务
根据xid 删除account_freeze表的冻结记录
4.cancel业务
减少金额
根据xid 修改account_freeze回滚状态
state 2
5.如何判断是否空回滚
6.如何避免业务悬挂
3.声明TCC接口
package com.jmj.gulimall.product.tcc;import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import io.seata.rm.tcc.api.LocalTCC;
import io.seata.rm.tcc.api.TwoPhaseBusinessAction;@LocalTCC
public interface AccountTCCService {@TwoPhaseBusinessAction(name="induct",commitMethod = "commit",rollbackMethod = "rollback")void induct(@BusinessActionContextParameter(paramName = "params") String params,@BusinessActionContextParameter(paramName = "money") int money);boolean commit(BusinessActionContext businessActionContext);boolean rollback(BusinessActionContext businessActionContext);}
package com.jmj.gulimall.product.tcc;import com.jmj.gulimall.product.dao.PmsSpuInfoTblMapper;
import com.jmj.gulimall.product.entity.SpuInfoEntity;
import com.jmj.gulimall.product.service.SpuInfoService;
import com.jmj.gulimall.product.vo.spu.PmsSpuInfoTbl;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Slf4j
@Service
public class AccountTCCServiceImpl implements AccountTCCService {@Autowiredprivate SpuInfoService spuInfoService;@Autowiredprivate PmsSpuInfoTblMapper pmsSpuInfoTblMapper;@Override@Transactional(rollbackFor = Exception.class)public void induct(String params, int money) {//0.获取全局事务IDString xid = RootContext.getXID();PmsSpuInfoTbl pmsSpuInfoTbl = pmsSpuInfoTblMapper.selectById(xid);if (pmsSpuInfoTbl != null) {return ;}//1.扣减可用余额SpuInfoEntity byId = spuInfoService.getById(9L);byId.setPublishStatus(byId.getPublishStatus() + money);spuInfoService.updateById(byId);//2.记录冻结金额 事务状态PmsSpuInfoTbl p = new PmsSpuInfoTbl();p.setUserId("123");p.setFreezeMoney(money);p.setState(0);p.setXid(xid);pmsSpuInfoTblMapper.insert(p);}@Overridepublic boolean commit(BusinessActionContext businessActionContext) {//0.获取全局事务IDString xid = businessActionContext.getXid();//1.删除冻结金额return pmsSpuInfoTblMapper.deleteById(xid) == 1;}@Overridepublic boolean rollback(BusinessActionContext businessActionContext) {//0.获取全局事务IDString xid = businessActionContext.getXid();PmsSpuInfoTbl pmsSpuInfoTbl = pmsSpuInfoTblMapper.selectById(xid);if (pmsSpuInfoTbl != null) {if (pmsSpuInfoTbl.getState() ==2) {//幂等操作return true;}Integer freezeMoney = pmsSpuInfoTbl.getFreezeMoney();//1.扣减可用余额SpuInfoEntity byId = spuInfoService.getById(9L);byId.setPublishStatus(byId.getPublishStatus() - freezeMoney);spuInfoService.updateById(byId);pmsSpuInfoTbl.setState(2);pmsSpuInfoTblMapper.updateById(pmsSpuInfoTbl);}else {PmsSpuInfoTbl pmsSpuInfoTbl1 = new PmsSpuInfoTbl();String params = businessActionContext.getActionContext("params").toString();pmsSpuInfoTbl1.setUserId(params);pmsSpuInfoTbl1.setState(2);pmsSpuInfoTbl1.setFreezeMoney(0);pmsSpuInfoTbl1.setXid(xid);pmsSpuInfoTblMapper.insert(pmsSpuInfoTbl1);}return true;}
}
@GetMapping("/testTcc")public R testTcc() {accountTCCService.induct("JMJ",12);return R.ok();}
package com.jmj.gulimall.coupon.controller;import com.jmj.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient(value = "gulimall-product",path = "/product/spuinfo")
public interface PmsFeignService {@GetMapping("/testTcc")public R testTcc();
}
@GetMapping("/tet/tcc")@GlobalTransactional(rollbackFor = Exception.class)public R tcc(){CouponEntity couponEntity = new CouponEntity();couponEntity.setCouponImg(UUID.randomUUID().toString());couponEntity.setCouponName(UUID.randomUUID().toString());couponService.save(couponEntity);pmsFeignService.testTcc();if (true){throw new RuntimeException("测试异常");}return R.ok();}
最终回滚
能和AT模式混用
4.SAGA模式
类似于工作流
无隔离性
5.SEATA高可用
1.实现微服务高可用和异地容灾
本地模拟复制一份 文件夹
把配置文件改成杭州集群
启动命令
seata-server.bat -p 8092
这样集群部署成功了
若出现容灾的情况下
利用nacos的配置热更新 就可以了
可以新建一个通用客户端配置
client.yaml
官网有详细配置
这里用我自己的简略版
#事务组的映射关系
service.vgroupMapping.seata-demo=defaultservice.enableDegrade=false
service.disableGlobalTransaction=false#与TC服务的通信配置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#rm配置
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
#tm配置
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
#undo配置
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
自动刷新 注解这里记录一下
/*** 优惠券信息** @author jiangmingji* @email 123456789@qq.com* @date 2024-03-21 21:24:36*/
@RefreshScope //动态从配置中心获取配置
@RestController
@RequestMapping("/coupon/coupon")
public class CouponController {@Autowiredprivate CouponService couponService;@Value("${coupon.user.name}")private String name;@Value("${coupon.user.age}")private Integer age;
微服务读取配置
这样给微服务 配上配置就可以了
seata:data-source-proxy-mode: AT #开启数据源代理的XA模式registry: #TC服务注册中心的配置,微服务根据这些信息取注册中心获取tc服务地址#参考tc服务自己的 registry.conf 中的配置,#包括:地址 namespace, group,application-name, clustertype: nacosnacos: #TCserver-addr: 127.0.0.1:8848group: DEFAULT_GROUPnamespace: "" #因为都在public 所以用空串application: seata-tc-serverusername: "nacos"password: "nacos"tx-service-group: seata-demo #事务组,根据这个获取tc服务的cluster名称 自己取的名称config:type: nacosnacos:server-addr: 127.0.0.1:8848group: 'SEATA_GROUP'dataId: 'client.properties'username: 'nacos'password: 'nacos'namespace: ""
重启服务
修改配置
将集群切换为杭州 HZ
成功注册到8092那个seata-server上面了
相关文章:
![](https://i-blog.csdnimg.cn/direct/18fba90f495845618d4912983efcf355.png)
Seata搭建
1.初识Seata Quick Start | Apache Seata 官网 2.准备nacos和 seata 启动nacos startup.cmd -m standalone账号nacos 密码nacos 搭建seata TC 这里下载的 1.4.2 seata-server-1.4.2 1.修改seata配置文件 registry.conf 这里我们使用nacos作为注册中心 和 配置中心 r…...
![](https://i-blog.csdnimg.cn/direct/9fc51a624613444baee53c372339f297.png#pic_center)
流浪猫流浪狗领养PHP网站源码
源码介绍 流浪猫流浪狗领养PHP网站源码,适合做猫狗宠物类的发信息发布。当然其他信息发布也是可以的。 导入数据库,修改数据库配置/application/database.php 设置TP伪静态,设置运行目录, 后台:/abcd.php/dashboard?…...
![](https://www.ngui.cc/images/no-images.jpg)
asammdf python 处理MF4文件库简介
asammdf 是一个功能强大的 Python 库,专门用于处理汽车行业常用的 MDF(Measured Data Format)文件。以下是 asammdf 的主要功能总结: 主要功能 读取和写入 MDF 文件: 支持 MDF 文件的版本 3.x 和 4.x。 能够读取和…...
![](https://www.ngui.cc/images/no-images.jpg)
【“软件工程”基础概念学习】
基础和相关概念 英文:Software Engineering 软:物体内部的组织疏松,受外力作用后容易改变形状软件: 计算机系统的组成部分,是指挥计算机进行计算、判断、处理信息的程序系统。通常分为系统软件和应用软件。借指某项活…...
![](https://i-blog.csdnimg.cn/img_convert/9c6b055b9def98019bad5a8a79c24a2a.png)
省森林防火应急指挥系统
森林防火形势严峻 我国森林防火形势十分严峻,森林火灾具有季节性强、发现难、成灾迅速等特点,且扑救难度大、影响范围广、造成的损失重。因此,构建森林防火应急指挥系统显得尤为重要。 系统建设模式与架构 森林防火应急指挥系统采用大智慧…...
![](https://www.ngui.cc/images/no-images.jpg)
一键整理背包界面功能
一键整理功能 游戏《帕鲁》中的背包界面有一键整理的功能,就是玩家随意拖拽背包格子里的物品,然后导致背包界面看起来很凌乱,比如物品a在一个格子里数量为1,另一个格子里数量为3,或者还有空格杂夹在有物品的格子旁边,一键排序功能可以解决这个问题,(将相同物品整合到一…...
![](https://i-blog.csdnimg.cn/img_convert/e6fc2e8f033b9f47295d2341822c38c3.jpeg)
给DevOps加点料:融入安全性的DevSecOps
从前,安全防护只是特定团队的责任,在开发的最后阶段才会介入。当开发周期长达数月、甚至数年时,这样做没什么问题;但是现在,这种做法现在已经行不通了。 采用 DevOps 可以有效推进快速频繁的开发周期(有时…...
![](https://www.ngui.cc/images/no-images.jpg)
uniapp 使用 pinia 状态持久化
1.创建文件 stores -index.js -global.js2.对应文件内容 index.js 安装插件 npm i pinia-plugin-persistedstate import { createPinia } from pinia; import persist from pinia-plugin-persistedstate; const pinia createPinia(); pinia.use(persist); export default pi…...
![](https://www.ngui.cc/images/no-images.jpg)
HarmonyOS鸿蒙-@State@Prop装饰器限制条件
一、组件Components级别的状态管理: State组件内状态限制条件 1.State装饰的变量必须初始化,否则编译期会报错。 // 错误写法,编译报错 State count: number;// 正确写法 State count: number 10; 2.嵌套属性的赋值观察不到。 // 嵌套的…...
![](https://i-blog.csdnimg.cn/direct/c9d72f3099284e8692ae72a88841286d.gif)
Java Web开发进阶——Spring Boot与Spring Data JPA
Spring Data JPA 是 Spring 提供的一种面向数据访问的持久化框架,它简化了 JPA 的实现,为开发者提供了一种快速操作数据库的方式。在结合 Spring Boot 使用时,开发者能够快速完成数据库访问层的开发。 1. 介绍Spring Data JPA 1.1 什么是Spr…...
![](https://i-blog.csdnimg.cn/direct/a407222a7b6b4ec982230805e670a5f8.png)
Vue Router4
Vue Router 是 Vue.js 官方的路由管理器。Vue Router 基于路由和组件的映射关系,监听页面路径的变化,渲染对应的组件。 安装: npm install vue-router。 基本使用: // src/router/index.js import {createRouter, createWebHa…...
![](https://www.ngui.cc/images/no-images.jpg)
计算机网络之---应用层协议概述
应用层协议概述 应用层协议是OSI模型中的第7层(应用层)定义的一组规则,用于支持和管理不同应用程序之间的通信。应用层协议定义了数据交换的格式、规则和约定,使得不同的系统或应用能够互相理解并正确地交换数据。它直接面向用户并…...
![](https://www.ngui.cc/images/no-images.jpg)
html + css 顶部滚动通知栏示例
前言 在现代网页设计中,一个吸引人的顶部滚动通知栏不仅能够有效传达重要信息,还能提升用户体验。通过使用HTML和CSS,我们可以创建既美观又功能强大的组件,这些组件可以在不影响网站整体性能的情况下提供实时更新或紧急通知。 本…...
![](https://i-blog.csdnimg.cn/direct/c3b136c8cc67455eb1ec02b4d8fb2b0e.png)
【Rust自学】11.6. 控制测试运行:并行和串行(连续执行)测试
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 11.6.1. 控制测试的运行方式 cargo test和cargo run一样,cargo test也会编译代码并生成一个二进制文件用于测试,…...
![](https://i-blog.csdnimg.cn/direct/b851981098064fdb960b56bd46d8f380.png)
某漫画网站JS逆向反混淆流程分析
文章目录 1. 写在前面1. 接口分析2. 反混淆分析 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Pyth…...
![](https://www.ngui.cc/images/no-images.jpg)
React 中事件机制详细介绍:概念与执行流程如何更好的理解
React 的事件机制是一个非常重要的概念,它涉及到 React 如何处理用户的交互事件。React 的事件系统与传统的 DOM 事件系统有所不同,它在底层使用了事件委托和合成事件(Synthetic Events)来优化性能。下面,我们将从 Rea…...
![](https://i-blog.csdnimg.cn/direct/e73c30fd98f546a8a861a30a370a9a9e.png)
Day04-后端Web基础(Maven基础)
目录 Maven课程内容1. Maven初识1.1 什么是Maven?1.2 Maven的作用1.2.1 依赖管理1.2.2 项目构建1.2.3 统一项目结构 2. Maven概述2.1 Maven介绍2.2 Maven模型2.3 Maven仓库2.4 Maven安装2.4.1 下载2.4.2 安装步骤 3. IDEA集成Maven3.1 配置Maven环境3.1.2 全局设置 3.2 Maven项…...
![](https://www.ngui.cc/images/no-images.jpg)
vue3模板语法+响应式基础
模板语法 1. disabled指令,可以用于禁用按钮 <button :disabled"isButtonDisabled">Button</button> //:disabled是一个指令,用于根据isButtonDisabled的值来动态控制按钮的禁用状态。 使用场景: 1.防止用户重复点击…...
![](https://www.ngui.cc/images/no-images.jpg)
【面试题】简单聊一下什么是云原生、什么是k8s、容器,容器与虚机相比优势
云原生(Cloud Native) 定义:云原生是一种构建和运行应用程序的方法,旨在充分利用云计算的优势。它涵盖了一系列技术和理念,包括容器化、微服务架构、自动化部署与管理等。特点:云原生应用程序被设计为可弹性…...
![](https://i-blog.csdnimg.cn/direct/1fc742ce992f43b29438ea08904c2a4e.png)
数据挖掘实训:天气数据分析与机器学习模型构建
随着气候变化对各行各业的影响日益加剧,精准的天气预测已经变得尤为重要。降雨预测在日常生活中尤其关键,例如农业、交通和灾害预警等领域。本文将通过机器学习方法,利用历史天气数据预测明天是否会下雨,具体内容包括数据预处理、…...
![](https://i-blog.csdnimg.cn/direct/8c15db5440a9422dbbb18e2193a9d031.png)
STM32如何使用内部晶振作为晶振
目录 前言 首先说明一下芯片内部并没有时钟, 而是内部振荡。使用内部振荡的好处是外部无需设计晶振电路 ,再说的简单点 ,不用外部晶振依然可以让单片机正常运转。 环境: 芯片:STM32F103C8T6 Keil:V5.24…...
![](https://i-blog.csdnimg.cn/direct/7018eb525e8f4c61956416b4ae13b748.png)
【Maui】导航栏样式调整
前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI,可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET MAUI 是一款开放源代码应用,是 X…...
![](https://i-blog.csdnimg.cn/direct/4339bad58073496cb0a746fcbceeab1e.png)
【黑马程序员三国疫情折线图——json+pyechart=数据可视化】
json数据在文末 将海量的数据处理成我们肉眼可以进行分析的形式,数据的可视化,可以分为两个步骤: 数据处理:利用三方网站厘清json层次格式化,再对文件的读取、检查是否符合JSON规范以及规范化、JSON格式的转化&#…...
![](https://i-blog.csdnimg.cn/direct/322caf0ea60e4969abab0c9f31f50d6c.png#pic_center)
如何实现多级缓存?
本文重点说一说在Java应用中,多级缓存如何实现。 多级缓存是比较常见的一种性能优化的手段,一般来说就是本地缓存分布式缓存。 本地缓存一般采用Caffeine和Guava,这两种是性能比较高的本地缓存的框架。他们都提供了缓存的过期、管理等功能。…...
![](https://i-blog.csdnimg.cn/img_convert/f492165ec033721785008bb4dd83e5a5.png)
Saas数据库迁移单租户数据
1、背景 租户使用Saas系统,用一段时间后要将系统、数据搬迁到自建服务器。该Saas系统没有按租户分库,且数据库数据量太大,需要将单租户的数据抽取出来。Saas系统使用Mysql5.7数据库,主要使用INFORMATION_SCHEMA.COLUMNS表进行数据…...
![](https://www.ngui.cc/images/no-images.jpg)
LeetCode100之括号生成(22)--Java
1.问题描述 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例1 输入:n 3 输出:["((()))","(()())","(())()","()(())","()()()&qu…...
![](https://i-blog.csdnimg.cn/direct/a5c5e526ccbd4ba59b19814cc503177e.png)
阿里云ios镜像源
阿里云镜像源:阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 下载centos7...
![](https://www.ngui.cc/images/no-images.jpg)
芯片:为何英伟达的GPU能在AI基础设施领域扮演重要角色?
英伟达的GPU之所以能在AI基础设施领域扮演重要角色,主要源于其硬件架构的优势以及其与深度学习算法的高度兼容性。以下是几个关键因素: 1. 并行计算能力 GPU(图形处理单元)本质上是为处理大量并行计算任务而设计的。与CPU相比&a…...
![](https://i-blog.csdnimg.cn/direct/282f4b56083f47a3b4211d0240aaddde.jpeg#pic_center)
Linux系统之hostname相关命令基本使用
Linux系统之hostname相关命令基本使用 一、检查本地系统版本二、hostname命令的帮助说明中文帮助说明 三、hostname命令的基本使用1. 查看计算机名2. 查看本机上所有IP地址3. 查看主机FQDN4. 查看短主机名 四、hostnamectl命令的使用1. 查看主机详细信息2. 设置主机名3. hostna…...
Domain Adaptation(李宏毅)机器学习 2023 Spring HW11 (Boss Baseline)
1. 领域适配简介 领域适配是一种迁移学习方法,适用于源领域和目标领域数据分布不同但学习任务相同的情况。具体而言,我们在源领域(通常有大量标注数据)训练一个模型,并希望将其应用于目标领域(通常只有少量或没有标注数据)。然而,由于这两个领域的数据分布不同,模型在…...
![](https://images2017.cnblogs.com/blog/1150339/201801/1150339-20180109183118207-406290855.png)
a0000网站建设/汕头百度推广公司
版本3.2.3 1、数据库操作中的连贯操作table(),在查询的时候可以切换表,但是在插入,更新的时候请不要使用。例如 D(user)->table(auth)->add($data); 操作会出问题,因为插入的时候会把非user表的字段删除 2.数据库操作的crea…...
![](/images/no-images.jpg)
网站空间试用/网站建设哪家公司好
Oracle 提供了强大的审计功能,可以针对用户级,系统级范围,以及标准审计,细粒度审计等多种方式来审计各种数据库层面上的操作。然很多中小型数据库需要记录用户的登陆登出信息,而又不希望牺牲太多的性能。基于这种情形&…...
![](https://images2017.cnblogs.com/blog/332990/201802/332990-20180209111748045-1510560368.png)
城乡建设环保部网站/seo经理
问题描述: SharePoint 运行状况分析器提示: 中文:数据库正在兼容性范围内运行,建议进行升级。 英文:Database running in compatibility range and upgrade recommended 此时去管理中心---升级和迁移---查看数据库状态…...
![](/images/no-images.jpg)
网站怎么建设?/怎么样建一个网站
想象一下,您想用Python开发一个平凡的最终用户桌面(非Web)应用程序。 构造项目文件夹层次结构的最佳方法是什么?理想的功能是易于维护,IDE友好,适用于源代码控制分支/合并以及易于生成安装软件包。尤其是:您将源放在哪…...
![](http://oqwym6cik.bkt.clouddn.com/20180715153163692892664.png)
贵阳地铁建设网站/seo是什么工作内容
2019独角兽企业重金招聘Python工程师标准>>> [toc] 网络协议(networking protocol) 网络协议即为计算机网络中进行数据交换而建立的规则、标准或约定的集合。网络协议是由三个要素组成:语义、语法、时序,人们形象地把这…...
![](/images/no-images.jpg)
wdcp v3搭建WordPress/seo诊断优化方案
【摘要】最近两个月都在学习 Linux 驱动,中间碰到了很多问题,进度比较缓慢。尽管不是班科出生的,但是还是觉得算法很有必要学一学。因此将数组元素查找作为自己算法开篇的第一篇博客,好好跟着平凡程序员的博客学习,内容…...