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

Firestore事务后立即读取数据不一致的原因排查

问题描述

在Flutter中使用Cloud Firestore Native模式时,遇到一致性异常问题:事务成功更新一个文档并创建另一个文档后,立即读取这两个文档,得到的却是更新前的旧快照,以及新创建文档exists==false的结果。

已知Firestore Native模式保证强一致性,理论上事务提交完成后,后续读取应获取最新数据。但在事务和读取之间加入1秒延迟后,就能稳定拿到事务完成后的正确文档版本。

已确认:

  • 代码中是等待事务完全完成后才执行读取操作
  • Cloud Functions第一代onCreate/onUpdate触发器的实际执行未干扰结果(比如未删除新创建的文档)

不带触发器的简单测试用例表现符合预期,代码如下:

final ref1 = FirebaseFirestore.instance.doc('Parents/parent1');
final ref2 = FirebaseFirestore.instance.doc('Children/child1');
await FirebaseFirestore.instance.runTransaction((transaction) async {
  final doc1 = await transaction.get(ref1);
  final doc2data = { 'value': doc1.data()!['value'], };

  transaction.update(ref1, {
    'children': FieldValue.arrayUnion(['child1']),
  });
  transaction.set(ref2, doc2data);
});
final doc1 = await ref1.get();
debugPrint('doc1:children: ${doc1.data()?['children']}');
final doc2 = await ref2.get();
debugPrint('doc2.exists: ${doc2.exists}');

测试用例的预期输出:

flutter: doc1:children: [child1]
flutter: doc2.exists: true
问题原因分析

这种“延迟一致性”并非Firestore强一致性机制失效,核心原因和客户端缓存逻辑、服务器数据同步窗口、Cloud Functions触发器的异步特性相关,具体拆解:

  1. 客户端本地缓存的 stale read
    Firestore Native客户端会维护本地缓存,事务提交后,客户端可能还未完成与服务器的最新数据同步,此时立即读取会命中本地旧缓存。加入延迟后,缓存同步完成,就能拿到最新数据。而不带触发器的测试用例正常,说明单纯的事务+本地读取不会触发该问题,需结合触发器的影响判断。

  2. Cloud Functions触发器的异步执行窗口
    第一代Cloud Functions的onCreate/onUpdate触发器是异步触发的,事务提交后,Firestore需要先将数据同步到全局存储节点,再触发函数执行。这个同步过程存在极短的时间窗口,若客户端读取刚好发生在窗口内,就可能读取到未完全同步的旧数据。

  3. 事务提交后的全局复制延迟
    事务的await仅代表客户端收到了服务器的提交成功响应,但服务器端还需完成数据的全局复制与索引更新。此时客户端立即读取若访问的是未完成复制的节点,就会拿到旧数据。延迟1秒后,全局复制完成,读取结果恢复正常。

内容的提问来源于stack exchange,提问作者Stephen Hu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:02:32