Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Persisted Query Collection direct writes validate against rows older than a queued refetch

已关闭
#2,029 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
30/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
sqlite, typescript
领域
backend, databases

调研方向

Start with packages/db-sqlite-persistence-core/src/persisted.ts and packages/query-db-collection/src/manual-sync.ts to trace when refetches are accepted and direct writes are validated. Read packages/query-db-collection/tests/ownership-lifecycle.oracle.test.ts and examine how its generators cover lock holders and direct-write kinds. Done means the oracle covers those interleavings and verifies the chosen behavior for insert, update, and delete.

由索引模型根据 Issue 内容生成。

描述

Problem

In a persisted Query Collection, a Query direct write can validate against rows that are older than a refetch the source has already committed.

The persistence wrapper gives a source commit() to core only when the transaction holds the wrapper's apply lock (packages/db-sqlite-persistence-core/src/persisted.ts, applyHydrationBufferedTransaction → applyMutex.run → applyBufferedSyncTransactionUnsafe → transaction.applyToCollection()). The lock can be busy for any of these reasons:

  • A durable write is slow.
  • A mutation confirmation is in progress (persistAndConfirmCollectionMutations).
  • Startup is in progress.
  • A reload is in progress.

While the lock is busy, a committed refetch waits in the lock queue. Its result is already in the Query cache, but core has not accepted it.

A direct write (writeInsert, writeUpdate, writeDelete) validates the key against core's accepted rows when it is called (packages/query-db-collection/src/manual-sync.ts). Thus it cannot see the waiting refetch. The commit of the direct write then waits behind the refetch, so the application order stays correct. Only the validation is incorrect.

Observed

Key k exists only in the waiting refetch:

Call Persisted Query Collection Query Collection without persistence
writeInsert(k) Passes validation. The direct write wins. Throws a duplicate-key error.
writeUpdate(k) Throws UpdateOperationItemNotFoundError. k keeps the refetch value. Succeeds.
writeDelete(k) Throws DeleteOperationItemNotFoundError. k stays until the next refetch. Succeeds.

No variant enters an error state. No variant causes SQLite and the collection to disagree.

main before the settlement-drop change shows the same validation results. Also, after writeInsert(k), its Query cache does not include k.

Reachability

The window is narrow. All of these conditions are necessary:

  1. The collection has persistence.
  2. A slow storage write or a mutation confirmation overlaps a refetch.
  3. A direct write targets a key that only the waiting refetch contains.

That key is not yet visible, so code that writes only keys it shows cannot hit this.

Options
  • Accept a source commit into core at commit(), and keep only the durable write behind the lock. The accepted view then follows commit order. Mutation confirmations are also built inside the lock, so their acceptance must move to the time they reserve the lock. If it does not, an older confirmation could overwrite newer server rows. This change touches the hydration laws and reserveCommitTurn.
  • Validate a direct write when it applies, not when it is called. The direct write already waits behind the refetch, so it would validate against the correct rows. Direct-write errors would change from a synchronous throw to a rejected receipt. This is a public API change.
Test gap

The Query ownership-lifecycle oracle (packages/query-db-collection/tests/ownership-lifecycle.oracle.test.ts) does not interleave direct writes with a persisted refetch that waits on a busy apply lock. A fix should add that generator dimension for each kind of direct write and each holder of the lock.

主要语言
TypeScript
星标
3.9k
派生
268
平均合并
1 天 2 小时
30 天内合并 PR
206

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

TanStack/db 的其他 Issue

查看 TanStack/db 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。