分布式事务之Seata讲解

news2024/11/26 10:47:37

文章目录

  • 1 Seata
    • 1.1 简介
    • 1.2 架构
    • 1.3 四种事务模式
      • 1.3.1 XA
        • 1.3.1.1 定义
        • 1.3.1.2 优缺点
        • 1.3.1.3 代码中实现
      • 1.3.2 AT
        • 1.3.2.1 定义
        • 1.3.2.2 全局锁
          • 1.3.2.2.1 AT模式脏写问题
          • 1.3.2.2.2 全局锁
        • 1.3.2.3 AT模式优缺点
        • 1.3.2.4 与XA模式区别
        • 1.3.2.5 代码中实现
      • 1.3.3 TCC模式
        • 1.3.3.1 定义
        • 1.3.3.2 TCC模式优缺点
        • 1.3.3.3 代码中实现
          • 1.3.3.3.1 业务需求
          • 1.3.3.3.2 增加表
          • 1.3.3.3.3 新建接口编写try、confirm、cancel接口
      • 1.3.4 Saga模式
        • 1.3.4.1 定义
        • 1.3.4.2 Saga模型优缺点
    • 1.4 模式对比
      • 1.4.1 4种模式对比
      • 1.4.2 AT和TCC模式区别

1 Seata

学习此文章前需要先 点击了解CAP,2PC,3PC,TCC

1.1 简介

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

点击了解Seata搭建

1.2 架构

seata 事务管理中有三个重要的角色:

  • TC(Transaction Coordinator):事务协调者:维护全局和分支事务状态,协调全局事务提交或回滚。
  • TM(Transaction Manager):事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM(Resource Manager):资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

在这里插入图片描述

1.3 四种事务模式

在继续学习使用SEATA之前,对seata介绍中提到的分布式事务 AT、TCC、SAGA 和 XA 事务模式这些名词有必要介绍一下

1.3.1 XA

1.3.1.1 定义

XA规范是X/open组织定义的分布式事务处理(DTP)标准,XA规范描述了全局的TM与局部之间的接口,几乎所有的主流的数据库都对XA规范提供了支持。
在这里插入图片描述
seata的XA模式
在这里插入图片描述
RM一阶段工作:

  • 注册分支事务到TC
  • 执行分支业务sql但不提交
  • 报告执行状态到 TC

TC二阶段的工作:
TC检测各分支事务执行状态

  • 如果都成功,通知所有RM提交事务
  • 如果有失败,通知所有RM回滚事务

RM 二阶段的工作:
接收 TC 的指令,提交或回滚事务

1.3.1.2 优缺点

优点:

  • 事务的强一致性,满足ACID原则。
  • 常用的数据库都支持,实现简单,并且没有代码侵入

缺点:

  • 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能极差。
  • 依赖关系型数据库实现事务

1.3.1.3 代码中实现

seatastarter已经完成了XA模式的自动装配,实现非常简单,步骤如下
修改yml文件(每个参与事务的微服务)
在这里插入图片描述

seata:
  data-source-proxy-mode: XA # 开启数据库源代理的XA模式

application启动类上添加: @EnableAutoDataSourceProxy
需要事务的方法或类上添加:@GlobalTransactional(rollbackFor = Exception.class)

@GlobalTransactional
public void saveAll(){
	User user=new User();
	user.setName("test");
	user.setAge(18);
	baseMapper.insert(user);

	//feign接口
	orderFeignService.saveFeigh();
	//手动控制异常回滚
	//throw new RuntimeException("测试回滚");
}

1.3.2 AT

1.3.2.1 定义

AT 模式是一种无侵入的分布式事务解决方案。在 AT 模式下,用户只需关注自己的 业务 SQL,用户的 业务 SQL 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作
AT模式同样是分阶段提交的事务模型,不过弥补了XA模型中资源锁定周期过长的缺陷
在这里插入图片描述
阶段一RM的工作:

  • 注册分支事务
  • 记录undo-log(数据快照)
  • 执行业务sql并提交
  • 报告事务状态

阶段二提交时RM的工作:

  • 删除undo-log即可

阶段二回滚时RM的工作:

  • 根据undo-log恢复数据到更新前

在这里插入图片描述

1.3.2.2 全局锁

1.3.2.2.1 AT模式脏写问题

两个事务同时进行时,没有做到事务隔离性,如下事务1已经减10,事务二也减10了,但是事务1异常回滚了,恢复快照,也只能恢复事务1的恢复成100。
在这里插入图片描述

1.3.2.2.2 全局锁

AT 模式用全局锁来解决上方问题。两个事务同时处理时,先获取全局锁的事务1会等待事务2释放DB锁,事务2获取不到全局锁,会有300ms的时间重试,一直获取不到就释放DB锁,事务1就能获取到DB锁,恢复数据了。
在这里插入图片描述

极端模式:
保存快照时会保存修改前和修改后的快照,万一事务一恢复数据时,发现现在的值和快照不一样,已经被动过,就会记录异常发送警告,由人工来处理
在这里插入图片描述

1.3.2.3 AT模式优缺点

AT模式的优点:

  • 一阶段完成直接提交事务,释放资源数据库资源,性能比较好
  • 利用全局锁实现读写隔离
  • 没有代码侵入,框架自动完成回滚和提交

AT模式缺点:

  • 两阶段之间属于软状态,属于最终一致
  • 框架的快照功能会影响性能,但比XA模式要好很多

1.3.2.4 与XA模式区别

与XA模式的最大区别:

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

1.3.2.5 代码中实现

application启动类上添加: @EnableAutoDataSourceProxy
需要事务的方法或类上添加:@GlobalTransactional(rollbackFor = Exception.class)

在XA模式配置基础下,只需修改data-source-proxy-mode: AT

seata:
  data-source-proxy-mode: AT# 开启数据库源代理的XA模式

业务表中增加undo_log` 表

DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (
  `id`  bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `branch_id` bigint(20) NOT NULL COMMENT '分支事务ID',
  `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '全局事务ID',
  `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '上下文',
  `rollback_info` longblob NOT NULL COMMENT '回滚信息',
  `log_status` int(11) NOT NULL COMMENT '状态,0正常,1全局已完成',
  `log_created` datetime(6) NOT NULL COMMENT '创建时间',
  `log_modified` datetime(6) NOT NULL COMMENT '修改时间',
   PRIMARY KEY (`id`),
  UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) 
) ENGINE = InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

1.3.3 TCC模式

1.3.3.1 定义

TCC 模式与 AC 模式非常相似,每阶段都是独立事务,不同的是 TCC 通过人工编码来实现数据恢复。需要实现三个方法:

  • Try:资源的检测和预留
  • Confirm:完成资源操作业务;要求Try成功Confirm一定要能成功。
  • Cancel:预留资源释放,可以理解为try的反向操作
    在这里插入图片描述
    seata中TCC工作模型:
    在这里插入图片描述

1.3.3.2 TCC模式优缺点

TCC 模式优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能好
  • 相比 AT 模型,无需生产快照,无需使用全局锁,性能最强
  • 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库

TCC模式缺点:

  • 有代码侵入,需要人为编写tryConfirmCancel接口,太麻烦
  • 软状态,事务是最终一致
  • 需要考虑 ConfirmCancel 的失败情况,失败seata会重试,可能重复处理,需要做好幂等处理

1.3.3.3 代码中实现

1.3.3.3.1 业务需求

需修改如下:

  • 修改方法,编写try、confim、cancel逻辑
  • 保证confirm、cancel接口的幂等性,幂等处理就是防止重复处理
  • 允许空回滚
    当某分支事务的try阶段阻塞时,可能导致全局事务超时而触发二阶段的cancel操作。在未执行try操作时先先执行了cancel操作,这时cancel不能做回滚,这就是空回滚
    在这里插入图片描述
  • 拒绝业务悬挂
    对于已空回滚的业务,如果以后继续执行try,就永远不可能confirmcancel,这就是业务悬挂。应当阻止执行空回滚后的 try 操作,避免悬挂。
1.3.3.3.2 增加表

为了实现空回滚,防止业务悬挂,以及幂等性要求。我们必须在数据库操作的同时,记录当前事务id和执行状态,为此我们设计了一张表(自己根据业务设计,主要为了存事务状态,和业务表相关字段)

DROP TABLE IF EXISTS `tcc`;
CREATE TABLE `tcc`  (
  `xid` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `business_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '业务id',
  `state` tinyint(1) NULL DEFAULT NULL COMMENT '事务状态,0:try   , 1:confirm ,   2:cancel',
  PRIMARY KEY (`xid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
1.3.3.3.3 新建接口编写try、confirm、cancel接口
@LocalTCC
public interface InsertTCCService {
	/**
	 * try逻辑,@TwoPhaseBusinessAction中的name属性要与当前方法名一致,用于指定try逻辑对应的方法
	 */
	@TwoPhaseBusinessAction(name = "insert",commitMethod = "confirm",rollbackMethod = "cancel")
	void insert(@BusinessActionContextParameter(paramName = "name") String name,
	            @BusinessActionContextParameter(paramName = "age")Integer age);

	/**
	 * 二阶段confirm确认方法,可以另命名,倒要保证与commitMethod一致
	 * @param context 上下文,可与i传递try方法的参数
	 * @return
	 */
	boolean confirm(BusinessActionContext context);

	/**
	 *  二阶段cancel回滚方法,可以另命名,倒要保证与rollbackMethod一致
	 * @param context
	 * @return
	 */
	boolean cancel(BusinessActionContext context);

}

新建实现类,实现上方接口,编写业务

@Service
public class InsertTCCServiceImpl extends ServiceImpl<InsertTCCMapper, Tcc>  implements InsertTCCService {
	@Autowired
	CouponService couponService;


	@Override
	public void insert(String name, Integer age) {
		// 防止业务悬挂,先判断有没有tcc表中有没有记录,如果有,一定是cancel执行过,要拒绝业务
		// 1、获取事务id
		String xid = RootContext.getXID();
		// 2、判断是否有记录
		Tcc byId = this.getById(xid);
		if (byId!=null){
			// cancel执行过,拒绝执行业务
			return;
		}

		// 业务
		TCoupon tCoupon = new TCoupon();
		tCoupon.setName(name);
		tCoupon.setAge(age);
		couponService.save(tCoupon);

		// 记录事务状态和业务id
		Tcc tcc = new Tcc();
		tcc.setBusinessId(tCoupon.getId());
		tcc.setState(0); // 0是try
		this.save(tcc);
	}

	@Override // 成功的方法
	public boolean confirm(BusinessActionContext context) {
		// 获取事务id
		String xid = context.getXid();
		// 根据id删除tcc记录
		boolean b = this.removeById(xid);
		return b;
	}

	@Override // try的反向,恢复业务修改的数据
	public boolean cancel(BusinessActionContext context) {
		// 获取事务id
		String xid = context.getXid();
		// 查询tcc表,获取我们寸的businessId
		Tcc tcc = this.getById(xid);

		// -----空回滚的判断,为null证明try没执行,需要空回滚,就是再添加一条tcc记录,state存cancel-----
		if (tcc == null){
			// 记录事务状态和业务id
			tcc = new Tcc();
			tcc.setBusinessId(context.getActionContext("name").toString()); // 从try传的参数获取,这个字段值要唯一
			tcc.setState(2); // 2是cancel
			this.save(tcc);
			return true;
		}

		// ----幂等处理,状态判断,防止重复处理-------
		if (tcc.getState() == 2){ // 已经提交过了
			return true;
		}


		// 根据businessId删除我们业务里新增的数据
		boolean b = couponService.removeById(tcc.getBusinessId());
		return b;
	}
}

需要事务的方法或类上(事务发起方TM)添加 @GlobalTransactional 注解
接口上添加 @LocalTCC 注解,注:该注解添加在接口上,而不是实现类上

方法上添加@TwoPhaseBusinessAction定义两阶段提交
该注解属性:

  • name:定义一个全局唯一值,一般为该方法名
  • commitMethod:自定义提交方法名(二阶段提交),需和提交方法名保持一致
  • rollbackMethod:自定义回滚方法名(二阶段回滚),需和

@BusinessActionContextParameter 加上该注解可传递参数到二阶段方法BusinessActionContext 上下文 可取到@BusinessActionContextParameter定义的参数

1.3.4 Saga模式

1.3.4.1 定义

Saga 模式是 SEATA 提供的长事务解决方案,在 Saga 模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。

Saga 模式适用于业务流程长且需要保证事务最终一致性的业务系统,Saga 模式一阶段就会提交本地事务,无锁、长流程情况下可以保证性能。
事务参与者可能是其它公司的服务或者是遗留系统的服务,无法进行改造和提供 TCC 要求的接口,可以使用 Saga 模式。

saga 模式是 seata 提供的长事务解决方案,也分为两个阶段:

  • 一阶段:直接提交本地事务
  • 二阶段:成功则什么都不做;失败则通过编写补偿业务来回滚。
    在这里插入图片描述

1.3.4.2 Saga模型优缺点

Saga模式优点:

  • 事务参与者可以基于事件驱动实现异步调用,吞吐高
  • 一阶段可以直接提交事务,无锁,性能好
  • 不用编写 TCC 中的三个阶段,实现简单
  • 补偿服务即正向服务的“反向”,易于理解,易于实现;

Saga缺点:

  • 软状态持续时间不长,失效性差
  • 没有锁,没有事务隔离,会有脏写
  • Saga 模式由于一阶段已经提交本地数据库事务,且没有进行 预留 动作,所以不能保证隔离性

1.4 模式对比

1.4.1 4种模式对比

XAATTCCSAGA
一致性强一致性弱一致(也是最终一致)弱一致(也是最终一致)最终一致
隔离性完全隔离基于全局锁隔离基于资源预留隔离无隔离
代码侵入有,要编写三个接口有,要编写状态机和补偿业务
性能非常好非常好
场景对一致性、隔离性有高业务的需求基于关系型数据库的大多数分布式事务场景都可以1、对性能要求较高的业务。2、有非关系型数据库要参与的业务1、业务流程长、业务流程多。2、参与者包含其他公司或遗留系统服务,无法提供TCC模式要求的三个接口

1.4.2 AT和TCC模式区别

一个分布式的全局事务,整体式两阶段提交(Try-[Comfirm/Cancel])的模型,在seata中,AT模式与TCC模式事实上都是基于两阶段提交实现的,它们的区别在于:

  • AT模式基于支持本地ACID事务的关系型数据库:
    • 一阶段prepare行为:在本地事务中,一并提交“业务数据更新”和“相应回滚日志记录”;
    • 二阶段 commit 行为:马上成功结束,自动异步批量清理回滚日志;
    • 二阶段 rollback 行为:通过回滚日志,自动生成补偿操作,完成数据回滚;
  • 相应的,TCC模式需要我们认为编写代码实现提交和回滚:
    • 一键端 prepare 行为:调用自定义的prepare逻辑(如插入、删除、修改等操作);
    • 二阶段 commit 行为:调用自定义的 commit 逻辑;
    • 二阶段 rollback 行为:调用自定义的 rollback 逻辑;

所以TCC模式就是把自定义的分支事务(提交回滚)纳入到全局事务管理中,seata中的TCC模式就是手动版的AT模式,它允许自定义两阶段的处理逻辑而不需要依赖AT模式的undo_log回滚表

参考链接:
https://blog.csdn.net/qq_48721706/article/details/122656490
https://blog.csdn.net/weixin_44152047/article/details/118110391
https://baijiahao.baidu.com/s?id=1712163514749816361&wfr=spider&for=pc

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

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

相关文章

云服务器配合CookieCloud插件,实现浏览器网站Cookie同步

CookieCloud是由方糖开发的一个浏览器网站Cookie同步工具&#xff0c;Cookie是一个可以短时间代表我们登录身份的凭证&#xff0c;CookieCloud同步Cookie其实就是在同步登录状态&#xff0c;由一个浏览器插件和一个可以自行搭建的服务器端组成&#xff0c;可以定时地、在本地加…

linux pl320 mbox控制器驱动分析 - (2) 消息传递示例

linux pl320 mbox控制器驱动分析 - &#xff08;2&#xff09;消息传递示例 1 Messaging from Core0 to Core12 Back-to-back messaging from Core0 to Core13 Messaging from Core0 to Cores 1, 2, and 3 using Auto Acknowledge4 Auto Link messaging from Core0 to Core1 us…

算法设计 || 第5题:钓鱼问题-北京大学网站在线算法题(贪心算法)

目录 &#xff08;一&#xff09;题目网址视频网址 &#xff08;二&#xff09;手写草稿思考 Part1: 慕课PPT Part2: 笨蛋的学习 &#xff08;一&#xff09;题目网址视频网址 北京大学网站在线算法题&#xff1a;1042 -- Gone Fishing (poj.org) 视频讲解&#xff08;北…

进一步了解傅里叶变换的应用(附案例代码)

傅里叶变换&#xff08;Fourier Transform&#xff09;是一种非常常见的数学工具&#xff0c;能够将一个函数&#xff08;或时域信号&#xff09;分解成一些基本频率的合成。它使我们可以将时域信号&#xff08;例如波形图&#xff09;转换成频域信号&#xff0c;因而更容易地看…

ArcGIS按比例缩放图斑

今天介绍一下&#xff0c;在ArcGIS中&#xff0c;当我们需要按比例缩放图斑时&#xff0c;该如何操作呢。 可以使用“缩放”工具对要素进行缩放&#xff08;使整个要素变大或变小&#xff09;。在处理比例略有误差的数据&#xff08;例如&#xff0c;来自多个源的细分宗地&…

ChatGPT背后的大预言模型 以及《ChatGPT全能应用一本通》介绍

大型语言模型已经彻底改变了我们通过自然语言处理进行交互的方式&#xff0c;使得更多的基于语言的应用程序成为可能&#xff0c;例如语言翻译&#xff0c;问答&#xff0c;文本摘要和聊天机器人。 由于这些模型是在大量文本数据集&#xff08;如书籍&#xff0c;文章和社交媒…

C learning_13 操作符前篇(条件操作符、 逗号表达式、 下标引用、函数调用和结构成员、 表达式求值)

目录 条件操作符 逗号表达式 下标引用、函数调用和结构成员 1. [ ] 下标引用操作符 2. ( ) 函数调用操作符 3. 访问一个结构的成员 表达式求值 1.隐式类型转换 2.算术转换 3.操作符的属性 条件操作符 条件操作符是一种用于简化条件表达式的运算符。它通常表示为问号 …

《游戏编程模式》--重访设计模式--学习

序 在线阅读地址&#xff1a; 命令模式 Design Patterns Revisited 游戏设计模式 (tkchu.me) 参考文章&#xff1a; GameDesignPattern_U3D_Version/Assets/002FlyweightPattern at master TYJia/GameDesignPattern_U3D_Version GitHub 看到了没见过的观点&#xff1a;…

我的算法基础实验代码-下篇

第一题 题目介绍 输入一些数值&#xff0c;求出现的次数最多的数。如果有多个并列&#xff0c;则从大到小输出。 解题思路 代码实现 package com.nineWeek;import java.util.*;/*** author WangYH* version 2021.1.3* date 2023/5/7 18:29*/public class NumMostTimes {pu…

第十四届蓝桥杯b组c/c++

D:飞机降落&#xff08;全排列&#xff09; #include<iostream> #include<cstring> using namespace std;const int N 12; int n; struct node{int t, d, l; //t为此飞机的最早降落时间 d为盘旋时间 l为降落所需时间 }p[N]; bool st[N];//DFS求全排列模型 bool d…

【真题解析】系统集成项目管理工程师 2021 年下半年真题卷

本文为系统集成项目管理工程师考试(软考) 2021 年上半年真题&#xff0c;包含答案与详细解析。考试共分为两科&#xff0c;成绩均 ≥45 即可通过考试&#xff1a; 综合知识&#xff08;选择题 75 道&#xff0c;75分&#xff09;案例分析&#xff08;问答题 4 道&#xff0c;75…

ChatGPT 学习与使用总结

ChatGPT 学习与使用总结 最近ChatGPT大火&#xff0c;2023有可能就是AGI元年了。近两个月使用下来&#xff0c;ChatGPT给我最深刻的感觉就是它所具备的理解和思维能力&#xff0c;第一次体验时真的是非常震撼&#xff0c;完全是之前各种『人工智障』智能助理所不能比拟的&…

Windows系统出现蓝屏怎么办?这些方法可以修复!

Windows 系统蓝屏死机&#xff08;BSOD&#xff09;&#xff0c;也被称为“停止错误”&#xff0c;是Windows系统最常见的故障之一。 当Windows遇到严重的故障时就会显示蓝屏&#xff0c;系统崩溃。蓝屏上显示一个停止代码&#xff0c;如"MEMORY_MANAGEMENT"&#xf…

NeRF与三维重建专栏(一)领域背景、难点与数据集介绍

前言 关于该系列专栏&#xff0c;主要介绍NeRF在三维重建中的应用&#xff08;这里我们特指MVS&#xff0c;multi-view stereo&#xff0c;也即输入带位姿的图片&#xff0c;输出三维结构例如点云、mesh等&#xff1b;并且后面的工作也都是围绕MVS with NeRF讨论的。虽然也有w…

人类与ChatGPT:互动中的共同进步

一、ChatGPT的发展历程 1. GPT模型 ChatGPT是由OpenAI推出的一款聊天机器人&#xff0c;其核心技术基于GPT模型。GPT模型&#xff08;Generative Pre-training Transformer&#xff09;是一种基于Transformer结构的预训练语言模型。它在大规模的文本语料库上进行无监督的预训…

解析 ip addr 的输出的内容含义

解读 ip addr 的输出的网络连接信息含义 一、ifconfig 与 ip addr 用过Linux的读者都知道&#xff0c;在Linux查看ip可以使用ifconfig&#xff0c;当然这个ifconfig属于net-tools 工具集&#xff0c;其来源于BSD&#xff0c;Linux从2001年就不对其进行维护了。那我们应该用什…

基于下垂控制的并网逆变器控制MATLAB仿真模型

资源地址&#xff1a; 基于下垂控制的并网逆变器控制MATLAB仿真模型资源-CSDN文库 主要模块&#xff1a; 建议使用MATLAB2021b及以上版本打开&#xff01; 功率计算模块、下垂控制模块、电压电流双环控制模块、虚拟阻抗压降模块 扰动设置&#xff1a; 在0.5秒到2秒始端设置…

微软出品的实用小工具

微软出品的实用小工具 分享一些微软出品的实用小工具&#xff0c;希望对大家有所帮助。 文章目录 微软出品的实用小工具SysinternalsSuite常用工具AutorunsprocdumpProcess Explorer进程监视器 Process MonitorpsloggedonAccessChk示例 PsToolsrdcmanTcpviewVmmap Sysinternals…

数据结构_树与二叉树

目录 1. 树的基本概念 1.1 树的定义 1.2 基本术语 1.3 树的性质 1.4 相关练习 2. 二叉树的概念 2.1 二叉树的概念及其主要特性 2.2 二叉树的存储结构 2.2.1 顺序存储结构 2.2.2 链式存储结构 2.3 相关练习 3. 二叉树的遍历和线索二叉树 3.1 二叉树的遍历 3.1.1 先…

基于微信小程序校内论坛系统

开发工具&#xff1a;IDEA、微信小程序 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 前端技术&#xff1a;vue、uniapp 服务端技术&#xff1a;springbootmybatis-plus 本系统分微信小程序和管理后台两部分&a…