跳到主要内容

captureCrudWrite()

function captureCrudWrite<TResult>(
port,
token,
write,
businessWrite
): Promise<TResult>;

Defined in: packages/rxdb-plugin-working-tree/src/working-tree/write-entry.ts:448

把一次普通 CRUD 写入包进工作树捕获的四步(FR-039)

Type Parameters​

Type ParameterDescription
TResult业务写入的返回类型

Parameters​

ParameterTypeDescription
portWorkingTreeCapturePort捕获端口,由调用方绑定到当前事务
tokenActiveBranchToken调用方在读取 / 实例化实体时捕获的 active 分支 token
writeCapturedWrite这一次要捕获的写
businessWrite() => Promise<TResult>尚未执行的业务写入

Returns​

Promise<TResult>

businessWrite 的返回值,原样透传

Throws​

StaleActiveBranchError token 过期;此时 businessWrite 一次都没被调用

Remarks​

四步顺序即契约:校验 token → 写业务实体 → 写入或合并完整单元 → 递增 workingTreeRevision。 调用方必须把这四步放在同一个事务里,任一步失败全部回滚。

三处顺序不能调换:

  • token 校验在业务写入之前。 挪到后面就成了「先写进去再发现分支不对,靠回滚收拾」。 raw 通道与批量写路径都已经为「拒绝发生在执行前」付过代价,最热的 CRUD 这条路没有理由退让。
  • 递增排在落条目之后。 反过来的话,条目写失败时 revision 已经 +1——而它是 commit 的 CAS 依据,一次失败的 save() 会让另一个 Tab 手里的 revision 凭空作废。
  • 读已有条目在落条目之前,且读的是库不是内存 dirty set。刷新一次页面 dirty set 就是空的, 于是 inversePatch 被记成刷新后的值,discard 从此退不回 HEAD,全程没有任何报错。

entryCount 的增量原样取自折叠(foldWorkingTreeEntry),捕获不自己数: 数第二遍就是第二份真相,而且是没有用例保护的那份。

Example​

await adapter.transaction(async tx => {
const port = createCapturePort(tx);
return captureCrudWrite(port, entity.branchToken, toCapturedWrite(entity), () => tx.upsert(entity));
});