当前位置: 首页 > news >正文

【Mysql系列】Mysql 多级隔离级别揭秘

目录

一、什么是隔离级别

1.1、为什么复合操作需要事务?

1.2、事务的 ACID 特性如何保障操作可靠性?

1.3、隔离性通过隔离级别来控制

二、为什么用多级隔离级别

2.1、事务并发执行时可能引发以下问题

2.1.1、脏读(Dirty Read)- 读未提交

2.1.2、不可重复读(Non-Repeatable Read)-  读已更新

2.1.3、幻读(Phantom Read)-  读已新增已删除

2.2、SQL 标准定义的四级隔离级别(从低到高)

三、Mysql-innodb RC隔离级别解决幻读底层流程揭秘

3.1、模拟RC和RR隔离的事务情况

3.2、MVCC实现揭秘

3.2.1、数据版本链结构化表格(从新到旧排序)基于UNDO_LOG

3.2.2、版本链核心机制解析

3.2.2.1、版本链如何形成?

3.2.2.2、版本链的核心作用:支撑 MVCC 并发读

3.2.2.3、版本链的生命周期(undo log 回收)

3.2.3、如何根据undo_log中的版本链进行定位确定读取哪个版本数据呢?

3.2.3.1、核心概念定义

3.2.3.2、核心分工 

3.2.3.3、当前读与快照读的本质区别

3.2.3.4、ReadView:可见性判断的 “裁判”

3.3、拿上述模拟RC与RR的事务例子进行说明

3.3.1、例子

3.3.2、RC隔离级别 ReadView 以及规则判断

3.3.3、RR隔离级别 ReadView 以及规则判断 

 3.3.4、RR存在幻读的特例


一、什么是隔离级别

        在 MySQL 中,当需要执行多条 SQL 语句(例如 “先查询数据状态再进行更新”、“跨表关联修改数据” 等场景)时,单条 SQL 的独立执行无法保证整体操作的可靠性。此时需引入事务机制,通过 ACID 特性屏蔽并发业务的干扰,确保操作的原子性与完整性:

1.1、为什么复合操作需要事务?

假设业务场景为 “查询账户余额后进行转账”,若不使用事务:

  1. 事务 A 查询余额为 1000 元,准备转账 500 元;
  2. 此时事务 B 同时修改该账户余额为 0 并提交;
  3. 事务 A 继续执行转账操作,最终余额变为 - 500 元,导致数据错误。

事务的作用:将多条 SQL 语句封装为一个不可分割的整体,要么全部成功,要么全部回滚,避免中间状态被其他业务干扰。MySQL 的事务机制通过 ACID 特性,为多条 SQL 的复合操作提供了 “原子性保护罩”:既屏蔽了并发业务的干扰,又确保了数据在复杂操作中的一致性,是解决 “查询 - 修改” 类业务场景可靠性问题的核心方案。

1.2、事务的 ACID 特性如何保障操作可靠性?

特性含义及作用示例场景
原子性(Atomicity)事务中的操作要么全部完成,要么全部回滚,不存在部分成功的状态。转账操作中,扣款与到账必须同时成功,否则回滚至初始状态。
一致性(Consistency)事务执行前后,数据从一个合法状态变为另一个合法状态,避免逻辑错误。转账后,转出账户减少的金额必须等于转入账户增加的金额,总余额不变。
隔离性(Isolation)多个事务并发执行时,相互之间不可见、不干扰,通过隔离级别避免脏读、幻读等问题。事务 A 查询余额时,不受事务 B 未提交的修改影响,确保读取的数据是已提交的合法版本。
持久性(Durability)事务提交后,数据修改永久保存,即使数据库崩溃也能恢复。转账成功后,即使服务器断电,重启后数据依然有效。

1.3、隔离性通过隔离级别来控制

隔离性(Isolation) 正是通过设置多级隔离级别来控制不同事务之间的干扰程度。多级隔离级别的设计本质是在 “数据一致性” 和 “并发性能” 之间寻找平衡,不同级别对应不同的并发控制策略,同时来针对解决脏读、幻读等问题。

二、为什么用多级隔离级别

2.1、事务并发执行时可能引发以下问题

2.1.1、脏读(Dirty Read)- 读未提交

事务 A 读取到事务 B 未提交的修改,若 B 回滚,A 读取的数据即为无效。

核心逻辑

  1. 事务 B 的更新未提交时,事务 A 若能读到这个 “临时数据”,就会引发脏读
  2. 事务 B 回滚后,事务 A 之前读的 “李四” 实际不存在,数据一致性被破坏
时间点事务 A 操作事务 B 操作stu 表(id=1)数据状态关键问题(脏读风险)
T1-(未开始查询)-(未开始更新)name='李牛牛'-
T2-(等待)update stu set name='李四' where id=1(执行更新,但未提交)name='李四'(事务 B 未提交的临时状态)事务 B 修改了数据,但还没确认(未提交)
T3select * from stu where id=1(查询数据)-(等待)读事务 B 未提交的name='李四'脏读发生事务 A 读到了事务 B 未提交的临时数据
T4-(等待)rollback(回滚事务,撤销 T2 的修改)回滚为name='李牛牛'事务 B 的修改被撤销,事务 A 之前读的数据 “无效” 了
T5-(后续查询 / 业务逻辑)-(结束)name='李牛牛'若事务 A 基于 T3 的脏数据做业务,会出问题

2.1.2、不可重复读(Non-Repeatable Read)-  读已更新

事务 A 多次读取同一数据时,事务 B 在期间提交了修改,导致 A 前后读取结果不一致。

核心逻辑

  1. 事务 A 在同一事务内,先读李牛牛,后读李四
  2. 差异源于事务 B 在事务 A 执行期间提交了修改,破坏了 “同一事务内数据可重复读” 的预期。
时间点事务 A 操作事务 B 操作stu 表(id=1)数据状态关键现象(不可重复读)
T1-(未开始)-(未开始)name='李牛牛'-
T2select * from stu where id=1(第一次查询)-(等待)name='李牛牛'事务 A 拿到初始数据
T3处理其他数据(耗时操作)-(等待)name='李牛牛'数据暂时未变
T4-(等待)update stu set name='李四' where id=1(执行更新)name='李四'(事务 B 修改后)事务 B 修改了数据,但未提交
T5-(等待)commit(提交事务 B)name='李四'(已提交)事务 B 的修改生效,数据永久改变
T6select * from stu where id=1(第二次查询)-(结束)name='李四'不可重复读发生同事务内两次查询结果不同

2.1.3、幻读(Phantom Read)-  读已新增已删除

事务 A 按条件查询数据时,事务 B 插入了符合条件的新数据,导致 A 再次查询时结果集 “幻觉” 般新增记录。

核心逻辑

        1.事务 A 先查询 “无数据”→执行删除→再查询 “有数据(李牛牛)”;

        2.差异源于事务 B 在事务 A 执行期间插入并提交了新数据,让事务 A 产生 “数据幻觉”。

时间点事务 A 操作事务 B 操作stu 表数据状态关键现象(幻读)
T1-(未开始)-(未开始)空表(假设初始无数据)-
T2select * from stu(第一次查询)-(等待)空表事务 A 看到 “没有数据”
T3delete from stu(删除操作,实际无数据可删)-(等待)空表逻辑上 “删除所有数据”,但无实际效果
T4-(等待)insert into stu value(2, '李牛牛')(插入数据)插入后:id=2, name='李牛牛'(事务 B 未提交)事务 B 新增数据,但未提交
T5-(等待)commit(提交事务 B)数据变为:id=2, name='李牛牛'(已提交)事务 B 的插入生效,数据永久存在
T6select * from stu(第二次查询)-(结束)id=2, name='李牛牛'幻读发生同事务内前后查询数据量 / 内容突变

    多级隔离级别的存在,正是为了通过不同策略解决上述问题,同时避免过度锁定导致性能下降。

    2.2、SQL 标准定义的四级隔离级别(从低到高)

    隔离级别解决的问题并发性能影响MySQL 默认级别(InnoDB)
    读未提交(Read Uncommitted)不解决任何问题,可能出现脏读、不可重复读、幻读最高(几乎无锁定)一般不使用
    读已提交(Read Committed, RC)解决脏读,仍可能出现不可重复读、幻读较高(行级锁,提交后释放)是(大多数业务场景)
    可重复读(Repeatable Read, RR)解决脏读、不可重复读,仍可能出现幻读(Innodb除外)中等(行级锁 + 间隙锁,防止数据修改)可配置使用
    可串行化(Serializable)解决所有并发问题(脏读、不可重复读、幻读)最低(完全串行化执行)仅特殊场景使用

    三、Mysql-innodb RC隔离级别解决幻读底层流程揭秘

    在 MySQL 的 InnoDB 存储引擎里,RC(读已提交)和 RR(可重复读)这两种隔离级别,借助 MVCC(多版本并发控制)机制来处理并发事务。

    3.1、模拟RC和RR隔离的事务情况

    时间点事务 A(trx_id=1)事务 B(trx_id=2)事务 C(trx_id=3)事务 D(查询事务)stu 表(id=1)数据版本变化关键现象(RR vs RC)
    T1begin
    update name=' 李牛牛' where id = 1
    -(未开始)-(未开始)-(未开始)事务 A 修改后:版本 1(trx_id=1,name=' 李牛牛 ')-
    T2commit-(未开始)-(未开始)-(未开始)版本 1 提交,成为 “已提交版本”-
    T3-(结束)begin
    update name=' 李四' where id = 1
    -(未开始)-(未开始)事务 B 修改后:版本 2(trx_id=2,name=' 李四 ')版本 2 未提交,仅事务 B 可见
    T4-(结束)处理其他数据(耗时操作)-(未开始)select * from stu where id = 1RR和RC读版本1(李牛牛
    T5-(结束)commit-(未开始)处理其他数据(耗时操作)版本 2 提交,覆盖版本 1,成为新 “已提交版本”-
    T6-(结束)-(结束)begin
    update name=' 王五' where id = 1
    处理其他数据(耗时操作)事务 C 修改后:版本 3(trx_id=3,name=' 王五 ')版本 3 未提交,仅事务 C 可见
    T7-(结束)-(结束)处理其他数据(耗时操作)select * from stu where id = 1(第二次查询)

    RC读版本2(李四

    RR读版本1(李牛牛)-解决不可重复度

    T8-(结束)-(结束)commit(等待)版本 3 提交,覆盖版本 2,成为最新 “已提交版本”
    T8-(结束)-(结束)-(结束)(等待)无新修改,版本 3 仍为最新

    3.2、MVCC实现揭秘

    MVCC 的核心逻辑是通过维护数据的多个版本,让不同事务在并发访问时,能基于各自可见的版本读写数据,以此在保证一定数据一致性的同时,提升并发性能 ,平衡了数据一致性需求与系统并发处理能力。InnoDB 的数据版本链使用的是回滚日志(UNDO_LOG)是 MVCC 的底层支撑,通过TRX_IDDB_ROLL_PTR串联历史版本,让读写操作在并发时互不阻塞;而 隔离级别的差异 本质是 “读操作遍历版本链时的规则不同”(快照是否固定、遍历范围如何),最终导致 “可重复读” 或 “不可重复读” 的结果。

    3.2.1、数据版本链结构化表格(从新到旧排序)基于UNDO_LOG

    版本层级

    (新→旧)

    id姓名

    TRX_ID

    (修改事务 ID)

    DB_ROLL_PTR

    (回滚指针,指向上一版本)

    版本来源

    版本 3

    (最新)

    1王五30x6446123(指向版本 2)事务 3 修改并提交
    版本 21李四20x6346413(指向版本 1)事务 2 修改并提交
    版本 11李牛牛10x77108a12(指向版本 0)事务 1 修改并提交

    版本 0

    (最旧)

    1李牛牛nullnull初始数据(无事务修改)
    3.2.2、版本链核心机制解析
    3.2.2.1、版本链如何形成?
    • 每次事务修改数据时,InnoDB 会:
      ① 复制当前行的旧版本到 undo log(回滚日志);
      ② 生成新版本,记录自身TRX_ID(修改事务的 ID);
      ③ 通过DB_ROLL_PTR将新版本与旧版本串联,形成单向链表

    • 示例中,数据从 “李牛牛”→“李牛牛”→“李四”→“王五” 的演变,对应版本 0→1→2→3 的链式结构。

    3.2.2.2、版本链的核心作用:支撑 MVCC 并发读

    InnoDB 的 MVCC(多版本并发控制) 通过版本链实现 “读不阻塞写,写不阻塞读”:

    • 读操作(SELECT):根据当前事务的隔离级别一致性快照,从版本链的最新版本开始,向前遍历,跳过以下版本:
              ✖️ 事务未提交的版本(TRX_ID对应事务未提交);
              ✖️ 事务 ID 大于当前快照可见范围的版本(仅 RR 级别会严格校验)。
    • 写操作(UPDATE/DELETE):直接生成新的版本,追加到版本链末端(旧版本保留在 undo log,供回滚或 MVCC 读使用)。
    3.2.2.3、版本链的生命周期(undo log 回收)
    • 版本链中的旧版本不会永久保留,InnoDB 会通过 purge 线程 回收 “不再被任何事务需要的旧版本”(如:当所有活跃事务的快照都不包含某旧版本时,该版本会被清理)。
    • 这解释了为什么长事务会导致 undo log 膨胀(长事务的快照保留时间长,旧版本无法及时回收)。
    3.2.3、如何根据undo_log中的版本链进行定位确定读取哪个版本数据呢?

    在 MySQL 的 InnoDB 存储引擎中,MVCC 通过 版本链(undo log) 和 ReadView 机制 实现高并发下的数据一致性。当事务执行 快照读(如普通 SELECT)时,会根据 隔离级别 生成 ReadView(RC 级别每次查询生成新 ReadView,RR 级别事务启动时生成一次),并按规则遍历版本链,直至找到可见版本或链尾。而 当前读(如 SELECT ... FOR UPDATE)则直接读取最新版本并加锁,不依赖 ReadView。通过这种方式,MVCC 将数据可见性判断转化为高效的内存操作,既避免了锁冲突,又通过隔离级别灵活控制一致性,实现了性能与正确性的平衡。

    3.2.3.1、核心概念定义
    概念本质典型操作示例核心特点
    当前读读取数据的最新版本,并对数据加锁(共享锁 / 排他锁),保证并发一致性。SELECT ... FOR UPDATE(排他锁)
    SELECT ... LOCK IN SHARE MODE(共享锁)
    INSERT/UPDATE/DELETE(隐式加锁)
    ① 读最新数据;② 加锁,阻塞其他事务修改
    快照读读取数据的历史版本(通过 MVCC 的版本链),无需加锁(逻辑无锁)。普通 SELECT * FROM table(未加锁时)① 读历史版本;② 无锁,高并发友好
    ReadView一个 “可见性视图”,用于判断哪个历史版本对当前事务可见的规则集合。由 InnoDB 自动生成(随事务 / 查询启动)包含活跃事务 ID、版本范围等元数据
    3.2.3.2、核心分工 
    概念作用依赖关系
    MVCC多版本并发控制,通过维护数据的历史版本链(undo log),实现读写并发无锁化。是快照读的底层支撑,当前读也依赖其版本链(但行为不同)。
    快照读读取历史版本(非最新数据),无锁,高并发友好。必须依赖 ReadView 判断哪个历史版本可见。负责高并发场景。
    当前读读取最新版本,并加锁(共享 / 排他锁),保证写操作原子性。不依赖 ReadView(加锁,直接读最新),直接访问最新数据并加锁。负责强一致场景(如写操作、临界资源读取)。
    ReadView一个 “可见性规则集合”,记录生成时刻的活跃事务 ID 等信息,指导快照读选择历史版本。是快照读的可见性判断依据,决定从版本链中选哪个版本。
    3.2.3.3、当前读与快照读的本质区别
    特性快照读(Snapshot Read)当前读(Current Read)
    依赖 ReadView✅ 必须通过 ReadView 选择历史版本❌ 直接读取最新版本(忽略 ReadView)
    加锁机制❌ 无锁(MVCC 实现读 - 写并发)✅ 加锁(S/X 锁,阻塞其他事务修改)
    典型操作SELECT * FROM table(无锁查询)SELECT ... FOR UPDATE
    INSERT/UPDATE/DELETE
    一致性保证由 ReadView 和隔离级别控制(RC/RR 的差异)强一致性(读取时锁定最新数据)
    3.2.3.4、ReadView:可见性判断的 “裁判”

    ReadView 是一个动态生成的内存结构,包含四个核心字段:

    • m_ids:当前活跃事务 ID 集合(未提交的事务);
    • min_trx_idm_ids中的最小事务 ID;
    • max_trx_id:下一个待分配的事务 ID(未来事务的起始 ID);
    • creator_trx_id:当前事务自身的 ID。

    当事务执行快照读时,InnoDB 会按以下步骤遍历版本链:

    获取当前 ReadView(根据隔离级别生成,RC 每次查询生成,RR 事务启动时生成);

    从最新版本开始,检查每个版本的trx_id是否满足以下条件:

    条件结果
    trx_id < min_trx_id✅ 版本可见(事务已提交)
    trx_id ≥ max_trx_id❌ 版本不可见(事务在 ReadView 生成后启动)
    min_trx_id ≤ trx_id < max_trx_id 且 trx_id ∈ m_ids❌ 版本不可见(事务未提交)
    min_trx_id ≤ trx_id < max_trx_id 且 trx_id ∉ m_ids✅ 版本可见(事务已提交)

    递归检查:若当前版本不可见,则通过DB_ROLL_PTR回溯到上一版本,重复上述判断,直到找到可见版本或遍历到链尾。

    3.3、拿上述模拟RC与RR的事务例子进行说明

    我们把上面的例子挪下来。

    3.3.1、例子
    时间点事务 A(trx_id=1)事务 B(trx_id=2)事务 C(trx_id=3)事务 D(查询事务)stu 表(id=1)数据版本变化关键现象(RR vs RC)
    T1begin
    update name=' 李牛牛' where id = 1
    -(未开始)-(未开始)-(未开始)事务 A 修改后:版本 1(trx_id=1,name=' 李牛牛 ')-
    T2commit-(未开始)-(未开始)-(未开始)版本 1 提交,成为 “已提交版本”-
    T3-(结束)begin
    update name=' 李四' where id = 1
    -(未开始)-(未开始)事务 B 修改后:版本 2(trx_id=2,name=' 李四 ')版本 2 未提交,仅事务 B 可见
    T4-(结束)处理其他数据(耗时操作)-(未开始)select * from stu where id = 1RR和RC读版本1(李牛牛
    T5-(结束)commit-(未开始)处理其他数据(耗时操作)版本 2 提交,覆盖版本 1,成为新 “已提交版本”-
    T6-(结束)-(结束)begin
    update name=' 王五' where id = 1
    处理其他数据(耗时操作)事务 C 修改后:版本 3(trx_id=3,name=' 王五 ')版本 3 未提交,仅事务 C 可见
    T7-(结束)-(结束)处理其他数据(耗时操作)select * from stu where id = 1(第二次查询)

    RC读版本2(李四

    RR读版本1(李牛牛)-解决不可重复度

    T8-(结束)-(结束)commit(等待)版本 3 提交,覆盖版本 2,成为最新 “已提交版本”
    T8-(结束)-(结束)-(结束)(等待)无新修改,版本 3 仍为最新
    3.3.2、RC隔离级别 ReadView 以及规则判断

    在读已提交(RC)隔离级别下,每一次执行快照读(select语句)时,都会生成一个ReadView,在上述例子中事务4,在事务3与事务2提交过程中 进行了2次查询,也就是生成了2次ReadView。

    快照读时机ReadView的值

    版本链数据访问规则

    (每一个版本进行遍历判断找到对应版本)

    第一次快照读,是事务2还未提交

    m_ids=[2,3,4](当前活跃事务 ID 集合(未提交的事务)

    min_trx_id =2(m_ids中的最小事务 ID)

    max_trx_id = 5(下一个待分配的事务 ID(未来事务的起始 ID)

    creator_trx_id =4(当前事务自身的 ID)

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(2)?

    (成立说明数据已经提交了,可以访问,只有版本链中的1满足,其他不满足)

    3、trx_id>max_trx_id(5)?

    (成立、并判断版本是否在m_ids中,如果在说明事务没有提交)

    4、min_trx_id(2)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本1,返回李牛牛

    第二次快照读,是事务2已提交,事务3未提交

    m_ids=[3,4](当前活跃事务 ID 集合(未提交的事务)

    min_trx_id =3(m_ids中的最小事务 ID)

    max_trx_id = 5(下一个待分配的事务 ID(未来事务的起始 ID)

    creator_trx_id =4(当前事务自身的 ID)

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(3)?

    (成立说明数据已经提交了,可以访问,遍历到版本链中的2满足)

    3、trx_id>max_trx_id(5)?

    (成立说明该事务是在ReadView生成以后才开始,不容许访问。不成立,可以访问)

    4、min_trx_id(3)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本2,返回李四

    3.3.3、RR隔离级别 ReadView 以及规则判断 

    在可重复读(RR)隔离级别下,仅在第一次执行快照读(select语句)时,都会生成一个ReadView,后面快照读复用,在上述例子中事务4,在事务3与事务2提交过程中 进行了2次查询,也就是生成了1次ReadView。

    快照读时机ReadView的值

    版本链数据访问规则

    (每一个版本进行遍历判断找到对应版本)

    第一次快照读,是事务2还未提交

    m_ids=[2,3,4](当前活跃事务 ID 集合(未提交的事务)

    min_trx_id =2(m_ids中的最小事务 ID)

    max_trx_id = 5(下一个待分配的事务 ID(未来事务的起始 ID)

    creator_trx_id =4(当前事务自身的 ID)

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(2)?

    (成立说明数据已经提交了,可以访问,只有版本链中的1满足,其他不满足)

    3、trx_id>max_trx_id(5)?

    (成立、并判断版本是否在m_ids中,如果在说明事务没有提交)

    4、min_trx_id(2)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本1,返回李牛牛

    第二次快照读,是事务2已提交,事务3未提交

    复用第一的快照读

    1、当前事务id == creator_trx_id(4)?

    (成立说明数据就是自己这个事务更改的)

    2、trx_id<min_trx_id(2)?

    (成立说明数据已经提交了,可以访问,只有版本链中的1满足,其他不满足)

    3、trx_id>max_trx_id(5)?

    (成立、并判断版本是否在m_ids中,如果在说明事务没有提交)

    4、min_trx_id(2)<=trx_id<=max_trx_id(5)

    (如果成立,说明这个版本事务没有被提交不能访问,不存在可以访问)

    (满足一个即可返回,顺序互斥判断)综上判断最终找到版本1,返回李牛牛

     3.3.4、RR存在幻读的特例

    在可重复读(RR)隔离级别下,仅在第一次执行快照读(select语句)时,都会生成一个ReadView,后面快照读复用。因为复用了 所以没有幻读的问题。

    特例:当两次快照读之间存在当前读(也就是说加了锁) ,ReadView会从新生成,导致产生幻读。

    http://www.dtcms.com/a/266966.html

    相关文章:

  • 使用Python绘制图片拆分工具
  • 风平浪静、无事发生
  • 论文解读:《DeepGray:基于灰度图像和深度学习的恶意软件分类方法》
  • OneCode 智能化UI布局与定位:注解驱动的视觉编排艺术
  • 图灵完备之路(数电学习三分钟)----数据选择器与总线
  • 使用alist+RaiDrive+webdav将百度夸克网盘变为本地电脑磁盘方法教程
  • 《人生顶层设计》读书笔记7
  • J20250704 算法题5道
  • css-多条记录,自动换行与自动并行布局及gap兼容
  • 智能私域运营中枢:从客户视角看 SCRM 的体验革新与价值重构
  • $route
  • Dash 安装使用教程
  • 浅层神经网络:原理与Python实现
  • Golang服务端处理Unity 3D游戏地图与碰撞的详细实现
  • docker运行的一些常用命令
  • SAP入门到放弃系列-流程订单-Process Instruction Category-自定义设置
  • QNetworkAccessManager异步请求有时候操作UI控件崩溃问题
  • ASP.NET MVC架构 路由提取
  • 第2期汽车模型数字工程沙龙,世冠科技分享汽车控制系统开发国产应用
  • 飞凌OK3568核心板与FPGA之间PCIe通信测试操作手册
  • FPGA实现40G网卡NIC,基于PCIE4C+40G/50G Ethernet subsystem架构,提供工程源码和技术支持
  • Day05: Python 中的并发和并行(1)
  • 堆的应用(建堆、堆排序、TOP-K问题)
  • 网安系列【3】之深入理解内容安全策略(CSP)
  • 迁移Ubuntu启动文件到另一块硬盘
  • ubuntu 18.04配置镜像源
  • 操作Choose Boot Java Run time for the IDE 导致AS重新安装后依然无法启动(已解决)
  • 考研408《计算机组成原理》复习笔记,第三章(3)——多模块存储器
  • Web前端:全选框的使用
  • Abase和ByteKV存储方案对比