VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Solana 并行执行:先看账户冲突,再看速度主张

Three students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.

English version · 区块链学习导航 · 上一篇

区块链学习 · 文章 BC044

三名学生在教室桌旁一起阅读书本,身边放有课本和文具。
学习场景配图;不代表照片中的学生正在学习区块链。

Solana 的账户访问模型帮助运行时识别哪些交易不必争用同一份可写状态。关键问题不是两笔交易是否调用不同程序,而是它们的有效账户访问是否冲突,以及选定的执行方式是否保留所需状态关系。

两笔交易可以共享只读账户,而不构成读写冲突。如果其中一笔写入另一笔读取或写入的账户,本篇课堂模型就必须把它们的执行分开。即使应用记录不同,共享的可写手续费支付账户也可能造成这种冲突。

本篇建立完整的六笔交易调度,核对最终状态,再改变一个容易漏掉的前提。目标是理解并行性从何而来,以及看似漂亮的调度图没有证明什么。

选择适合你的阅读路线

本篇目录

先理解只读与可写访问,再读六张交易卡,列出冲突边,并检查三轮调度。最后测试共享手续费支付账户的变化题,完成练习并核对答案。

所有账户名称、程序操作和时间单位都是虚构的。不创建真实账户、交易、签名、付款或部署。练习采用明确给定的调度模型,不复现生产验证节点的完整调度器。

资料核对于2026年10月12日。实现参考固定为 Agave v3.0.0;当前文档只支持文中指出的账户、指令和处理概念,不能据此推出吞吐量排名或某项升级已启用。

返回目录 · 下一节

1. 为什么账户访问属于架构问题

Solana 指令指明调用的程序及其使用的账户。交易汇集指令和相关账户信息,使运行时在程序操作执行完成之前,就能知道共享状态的访问情况。

Solana 指令文档介绍程序标识符、账户列表和指令数据。交易结构文档则说明所描述消息格式中的签名者和只读信息。

本篇采用已经解析完成的有效访问集合:相关账户地址均已确定,调度模型实际采用的只读或可写分类也由题目给出。我们不手动解码交易格式,也不解析地址查找表。

这可以避免一个隐蔽的捷径:某条指令的小型应用账户列表,不一定就是整笔交易的完整访问集合。支付手续费和其他指令可能引入共享可写账户,而过度简化的应用图会把它们漏掉。

返回目录 · 下一节

2. 只读、可写与签名者是不同标签

只读分类允许相应访问,但不把该账户视为这笔交易的可写账户。在本模型中,可写访问需要与其他读取和写入互斥。它是账户级分类,并不表示某条指令一定修改账户的每一个字节。

签名者信息回答授权问题,可写信息回答访问问题。获授权程序修改某账户的数据,不代表该账户本身一定要作为签名者;签名授权方自己的账户数据,也不一定被应用操作修改。

这些标签都不能代替程序检查。把账户标为可写,不会授予随意更改他人数据的权限,也不能绕过账户所属程序和运行时规则。模型假定有效性与授权要求已分别满足。

为便于表达,R(T) 表示 T 的有效只读集合,W(T) 表示有效可写集合。对可写账户的读取已包括在 W(T) 中,不应再把它列入 R(T),仿佛这笔交易只是读取者。

返回目录 · 下一节

3. 冲突判断方法

在课堂模型中,如果任意一笔交易的可写账户,出现在另一笔的只读或可写集合中,两笔交易就冲突。仅共享只读账户不会造成冲突。

等价的检查方式是比较三个交集:W(A) 与 W(B)、W(A) 与 R(B)、R(A) 与 W(B)。只要任何一个非空,A 与 B 就不能安排在同一执行轮次。若全部为空,在题目给定前提下,账户访问允许二者配对。

固定版本的 Agave v3.0.0 账户处理源码包含读写锁逻辑,以及区分共享读取和写入冲突的测试。其批次处理有实现专用选项;本篇轮次只是教学模型,不表示同一批次中的冲突交易必然被拒绝,或生产系统一定按本图运行。

冲突边表示访问需要协调,并不决定哪笔交易优先、哪笔应被纳入,也不表示任何一笔无效。这些都属于其他判断。

返回目录 · 下一节

4. 建立六张交易卡

虚构程序 P 管理五个存储普通整数的数据账户:C、X、Y、Z 和 W。初始值为 C=2、X=10、Y=20、Z=0、W=0。这些是课堂计数值,不是代币余额或现实测量值。

每笔交易都读取同一个保持不变的程序账户 P。每笔还各有一个不同的可写手续费支付账户 f1 至 f6。这些账户彼此不同,也不同于所有应用账户;资源充足,手续费变化不影响五个计数值。

其他必要访问均被题目设定为共享只读访问,或互不冲突的独有访问。不存在隐藏的共享可写账户、跨程序调用、升级或其他交易。每项操作在规定状态条件下都成功。

  • T1:R={C,P};W={X,f1}。把当前 C 加到 X。
  • T2:R={C,P};W={Y,f2}。把当前 C 加到 Y。
  • T3:R={X,P};W={Z,f3}。把当前 X 复制到 Z。
  • T4:R={P};W={C,f4}。把 C 设为3。
  • T5:R={P};W={X,f5}。把当前 X 翻倍。
  • T6:R={Y,P};W={W,f6}。把当前 Y 复制到 W。

参考串行顺序为 T1、T2、T3、T4、T5、T6。我们希望保留冲突交易对在此顺序中的先后关系,同时让不冲突的工作共享一个轮次。

返回目录 · 下一节

5. 推导六条冲突边

T1 与 T3 冲突,因为 T1 写 X,而 T3 读 X;T1 与 T5 冲突,因为两者都写 X;T1 还与 T4 冲突,因为 T1 读 C,而 T4 写 C。

T2 与 T4 通过 C 冲突,与 T6 通过 Y 冲突;T3 与 T5 通过 X 冲突。全部六个无序冲突对是:T1–T3、T1–T4、T1–T5、T2–T4、T2–T6、T3–T5。

T1 与 T2 都读 C 和 P,但写入不同应用账户,并使用不同支付账户,因此没有冲突边。T3 与 T6 也读取不同数据、写入不同目标,只共享只读的 P。

此处应检查完整性。六笔交易共有十五个无序交易对。仔细的答案应分类全部十五对,而不是只找出最明显的几处冲突。在给定访问前提下,其余九对兼容。

返回目录 · 下一节

6. 保留选定的冲突顺序

参考顺序为每条冲突边赋予方向:T1 必须先于 T3、T4、T5;T2 必须先于 T4、T6;T3 必须先于 T5。不能仅因两笔交易的编号不同,就额外要求它们按编号先后执行。

一种允许的调度是:

  1. 第1轮:T1 与 T2。
  2. 第2轮:T3、T4 与 T6。
  3. 第3轮:T5。

每轮内部的交易互相兼容,每条有向冲突边都从较早轮次指向较晚轮次。T6 可以移到 T5 前面,因为二者不冲突。T4 可以与 T3 同轮,虽然 T4 写 C,但 T3 读的是 X,不是 C。

本练习必须同时做这两种检查。只检查每轮内部,可能意外颠倒跨轮依赖;只检查先后顺序,又可能漏掉同轮中互相冲突的操作。

返回目录 · 下一节

7. 核对执行后的状态

第1轮开始时 C=2。T1 把 X 从10改为12;T2 把 Y 从20改为22。C 仍为2,Z 和 W 仍为0。两笔交易都不需要对方产生的结果。

第2轮在第1轮两笔交易都完成后开始。T3 把 X=12 复制到 Z;T4 把 C 设为3;T6 把 Y=22 复制到 W。按给定访问集合,这些操作兼容,得到 C=3、X=12、Y=22、Z=12、W=22。

第3轮把 X 从12翻倍为24。最终应用状态为 C=3、X=24、Y=22、Z=12、W=22。手续费支付账户余额不在这份计数计算中,但其可写访问已纳入冲突分析。

现在重放参考串行顺序:T3 仍在 T5 翻倍 X 之前复制12;T1 与 T2 仍在 T4 修改 C 之前读取 C。因此得到相同最终计数值。调度保留的是相关依赖,而不只是把方框排得好看。

返回目录 · 下一节

8. 不同串行顺序可能产生不同结果

假设有人把 T4 移到 T1、T2 之前。C 在两笔交易读取之前变成3,所以 T1 得到 X=13,T2 得到 Y=23。如果 T3 随后复制 X,T5 再将其翻倍,最终状态就会是 C=3、X=26、Y=23、Z=13、W=23。

这可能是另一种串行顺序的结果,却不是本题选定参考顺序要求的结果。调度器不能以“每个操作单独看都格式正确”为理由,随意改变这一关系。

类似地,把 T5 放到 T3 之前,会改变 T3 读到的内容。T1 之后再执行 T5,X 为24,T3 就会存下 Z=24,而不是12。正确性取决于冲突访问需要保留的顺序。

本例区分两个问题:在给定访问模型下,操作能否安全重叠?要保留的究竟是哪一种顺序?解决前者,不代表可以随意选择后者的答案。

返回目录 · 下一节

9. 共享手续费支付账户的变化题

把 f1 至 f6 换成同一个可写支付账户 S,应用操作保持不变。现在每一对交易的可写集合都共享 S,因此在本练习模型中,每一对都冲突。

每个无冲突轮次只能放一笔交易,六笔就需要六轮,而不是三轮。几组应用记录表面上仍然互不相干,但完整访问集合揭示了共同依赖。

这是概念诊断,不是建议创建或充值更多账户。真实设计还要考虑授权、运维和资源限制;也不能据此断言代付手续费交易具有某个固定吞吐量,生产调度及实现细节仍然重要。

有用的阅读习惯是:在接受并行性主张前,索取完整有效账户集合。“不同用户”或“不同目录记录”不能证明独立,因为它们可能共享另一个可写资源。

返回目录 · 下一节

10. 声明过多或过少的访问

假设 T1 实际只读取 C,但其有效分类却不必要地把 C 设为可写。此时它会与 T2 对 C 的读取冲突。即使这条程序路径没有修改 C,原来的第1轮也不再通过模型检查。

访问声明描述运行时必须允许并协调的范围,不只描述阅读者从某次成功示例中预计发生的写入。过多的可写分类,因此可能减少可用的并行组合。

反过来的捷径更有问题:某个操作不能一面修改 X,一面假装自己只有读取 X 的权限。省略必要访问而得到的“更多并行”,并没有解决状态冲突。

同样,同一个可写账户中存放两个字段,并不会让它们在账户级模型中自动成为可分别加锁的独立资源。调整状态布局可能改变依赖,但也改变了设计,必须保持应用所需的不变量。

返回目录 · 下一节

11. 可以被调度,不代表交易完全有效

六张卡假定签名、授权、资源和程序条件都满足。如果去掉这些前提,即使账户与邻近交易不冲突,交易也可能因其他原因失败。

Solana 交易处理流程文档介绍调度之外的检查与处理,包括签名验证、结构检查、账户加载和指令执行。其费用与失败处理也提醒我们:不能把所有失败尝试都理解为绝对没有任何变化。

本篇不实现这些阶段,也不重建完整费用账。提到它们,是为了限制结论:账户集合兼容只是一个调度性质,不能证明授权、执行成功、被纳入区块或最终确定。

同理,节点上的并发执行也不是网络共识的完整描述。账户冲突练习没有说明所有网络参与者如何就历史达成一致,不能把它宣传成解决了整个共识问题。

返回目录 · 下一节

12. 三轮究竟衡量了什么

如果每笔交易都恰好用一个虚构时间单位,每轮内资源无限,协调没有开销,那么三轮调度需要三个单位。按相同玩具前提,六步参考串行调度需要六个单位。

这是模型比较,不是实测生产速度提高一倍。真实交易成本不同,可用处理器核心、内存访问、账户加载、调度开销和其他限制,都可能让兼容操作无法一起运行。

模型中的依赖链 T1 先于 T3、T3 先于 T5,已经要求至少三个有序执行位置。给出的调度达到这个下界,因此在单位时长前提和选定冲突顺序下,三轮是最优结果。

如果改变成本或可用执行资源,优化问题也随之变化。冲突图提供约束证据,却不是性能基准、确认时延承诺或区块链排名。

返回目录 · 下一节

13. 练习:修复提议的调度

除题目明确修改外,使用原来的六个不同支付账户,以及原参考顺序。

  1. 学生提出第 A 轮={T1,T2,T6},第 B 轮={T3,T4},第 C 轮={T5}。哪项冲突使第 A 轮不成立?
  2. 另一名学生提出先执行 {T3,T4,T6},再执行 {T1,T2},最后 {T5}。每轮内部都无冲突,为什么调度仍错误?
  3. 如果 T1、T2、T3 已完成,T4 与 T5 能否共享一轮?
  4. 如果六笔都共享可写支付账户 S,共有多少条冲突边?本模型至少需要几轮?
  5. 原第1轮之后,如果先执行 T5 再执行 T3,Z 会得到多少?
  6. 两笔兼容交易调用同一个只读程序 P,会不会仅因程序标识符相同就发生冲突?

答案与推理

  1. T2 写 Y,T6 读 Y,因此不能在本模型中同轮执行,而且选定顺序要求 T2 先于 T6。把 T6 移到第 B 轮可以修复这一问题。

2. 它颠倒了必要依赖:T3 在 T1 写入前读取 X;T4 在 T1、T2 读取前修改 C;T6 在 T2 写入前读取 Y。没有跨轮顺序检查,仅有轮内兼容还不够。

3. 可以,前提是使用题目给出的集合。T4 写 C 和 f4,T5 写 X 和 f5,只共享只读 P;必要前置交易也都已完成。

4. 共有十五条边,对应六笔交易的每一个无序交易对。任何两笔都不能同轮,所以需要六轮。这来自有效访问集合的改变,不是应用计数计算得出的结果。

5. T1 先令 X=12,T5 再令 X=24,T3 随后复制该值。因此 Z=24,与原要求的 Z=12 不同。

6. 不会。仅共享只读 P 不造成读写冲突,但仍需检查其他账户,包括支付账户和所有指令使用的账户。

返回目录 · 下一节

14. 简明复核清单

接受“这些交易可以并行执行”的说法之前,应索取有效账户集合、只读与可写分类、冲突的参考顺序,以及假定的资源限制。

随后逐对检查,保留每一项必要依赖,并将结果状态与选定的串行解释比较。最后说明范围:它证明的是在声明前提下可行的调度,不是完整有效性、最终性或实际墙钟时间性能。

这份清单还可以解释某个具体主张为什么失败,而不必归咎于整个架构。共享支付账户、不必要的可写账户,或漏掉的读取依赖,都可能足以说明某个提议组合为何并不独立。

返回目录 · 下一节

15. 常见问题

有冲突,就表示交易无效吗?

不是。冲突表示在本模型中,两种访问需要协调。两笔交易都可能按合适顺序成功执行。调度限制与签名失败、程序条件不满足是不同问题。

本练习会并行安排同一笔交易内部的指令吗?

不会。练习调度的是完整交易,内部动作按给定条件处理,不重排同一交易的指令。处理流程资料描述的是顺序执行指令。

读取同一个账户,是否必须使用不同副本?

不必。本例共享只读访问之所以兼容,是因为两种操作都不修改该账户。如果加入并发写入者,分析就会改变,并产生冲突。

返回目录 · 下一节

资料来源与后续阅读

以下一手资料核对于2026年10月12日,新加坡时间:

  • Solana 指令:指令中的程序、账户和数据组成。
  • Solana 交易结构:所述消息格式中的账户、签名者与只读信息。本篇不依赖当前格式上限或升级启用结论。
  • Agave v3.0.0 账户处理及锁测试:共享读取与写入冲突的固定版本实现参考。课堂调度器没有复现其实现专用批次选项。
  • Solana 交易处理流程:账户冲突调度之外的处理与验证职责。只用于有限概念,不提供费用设置、交易提交或协议上限建议。

如果不熟悉与串行状态转移的比较,可回看之前的确定性执行课程。下一篇架构课程将跟踪 Fabric 的背书、排序和验证阶段,解释为何交易已经排序,仍可能无法通过更新应用状态所需的检查。

返回目录