跳到主要内容

事务

这篇讲的是当前实现里的事务事件机制,不是鼓励你在业务层直接依赖某个公开 rxdb.transaction(...) API。

结论

  • 事务主要由 adapter 层负责
  • RxDB 核心层额外做了一层事件缓冲
  • 事务期间,非事务事件会先进入缓冲队列
  • COMMIT 后再按原顺序统一派发
  • ROLLBACK 后直接丢弃缓冲事件

事务事件关系图

事件时序

当前核心逻辑

RxDB.dispatchEvent() 的判断是:

if (this.#transaction_event_pending && isTransactionEvent(event) === false) {
this.#need_dispatch_events.push(event);
} else {
listeners.forEach(listener => listener.call(this, event));
}

配合 #init_event() 里的监听器,结果就是:

  1. TRANSACTION_BEGIN 立即派发,并把 transaction_event_pending 置为 true
  2. 事务期间的普通实体事件先进入 #need_dispatch_events
  3. TRANSACTION_COMMIT 立即派发,然后顺序重放缓冲事件
  4. TRANSACTION_ROLLBACK 立即派发,然后清空缓冲,不做重放

为什么这么设计

如果事务中的 CREATE / UPDATE / REMOVE 事件立刻通知 UI,界面会看到中间态。

这层缓冲的意义很直接:

  • 提交前不暴露半成品状态
  • 回滚时不用再补一轮“撤销通知”
  • 查询订阅尽量只看到最终结果

业务层怎么写

日常业务代码仍然优先使用:

  • save()
  • remove()
  • saveMany()
  • removeMany()

如需控制 adapter 级事务,属于更底层的能力,不应在基础业务文档中将其作为常规主入口。