You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase事务中transaction.get()即时返回结果的原理探究

Firestore事务中transaction.get()“即时获取”的原理

首先明确:Firestore不会提前预加载数据库(或部分数据)副本,transaction.get()的同步即时感,完全来自它的乐观锁事务执行机制,具体拆解如下:

  • 事务的执行逻辑是「尝试-校验-重试」循环:
    当你调用db.runTransaction时,Firestore会把你的事务代码块(也就是那个lambda)提交执行。只有当代码块执行到transaction.get(ref)这一行时,才会触发对应文档的读取——如果本地缓存有该文档的最新版本,直接同步返回;没有的话就从服务端拉取最新数据,拉取完成后再继续执行下一行代码。

  • 不需要提前知晓要读取的文档:
    Firestore用的是乐观锁机制,它不会在事务开始前锁定或预加载任何数据。事务执行过程中,你按需调用transaction.get()读取指定文档,Firestore会记录这些文档的版本号。当你的代码块执行完所有逻辑(比如修改数据准备提交),Firestore会检查这些文档的版本号是否和读取时一致:

    • 如果一致,说明没有其他客户端修改过,直接提交事务里的写入操作;
    • 如果不一致,就自动重试整个代码块(重试次数默认有上限),重试时会重新读取这些文档的最新数据,再执行你的逻辑。
  • 关于“同步”的说明:
    你看到的val data = transaction.get(ref)是同步调用,指的是在事务的单次尝试内,这个get操作会阻塞到拿到数据才继续执行下一行,所以你感觉是“即时完成”。但整个runTransaction方法本身是异步的(底层是异步调度),只是代码块内部的逻辑是同步串行的。

举个简单的流程例子:

  1. 第一次尝试执行事务代码块,先读exampledoc,再读exampledoc2,然后修改数据准备提交;
  2. Firestore检查这两个文档的版本是否没变,没变就提交成功;
  3. 如果期间有其他客户端改了exampledoc,Firestore就会重试整个代码块,重新读取两个文档的最新数据,再执行你的逻辑。

内容的提问来源于stack exchange,提问作者Gabriel Maia Gondim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:05:22