google-cloud-firestore - 基于不存在文档的 Firestore 事务(集合级别锁定不可用)
问题描述
基于这个SO answer,我知道 firestore 在事务中没有集合级别锁定。就我而言,在写入集合之前,我必须确保用户集合中的用户名字段是唯一的。为此,我编写了一个执行此操作的事务:
- 对 users 集合执行查询以检查是否存在 username=something 的文档
- 如果确实存在,则失败并从事务返回错误
- 如果它不存在,只需为我要更新/创建的 userId 运行写入操作。
现在这里的问题是,如果两个客户端同时尝试运行此事务,则两者都可能查询集合,并且由于集合未锁定,一个客户端可能会插入/更新集合中的文档,而其他客户端将看不到它。
我的假设正确吗?如果是,那么如何处理这种情况?
解决方案
您尝试做的事情实际上不可能以原子方式进行,因为不可能对您无法使用 ID 识别的文档进行安全交易。get()
这里的问题是,只有当您可以添加或修改特定文档时,事务才是“安全的” 。由于您不能get()
使用文档中的字段值来创建文档,因此您不知所措。
如果您想确保 Firestore 中任何内容的唯一性,则需要将该唯一性编码到文档 ID 本身中。在最简单的情况下,您可以使用用户名作为新集合中文档的 ID。如果你这样做了,你的交易可以简单地get()
通过用户名输入所需的文件,检查它是否存在,如果不存在则编写文件。否则,交易可能会失败。
请记住,由于 Firestore 中的文档 ID 存在限制,如果您的用户名可能违反规则,您可能需要对该用户名进行转义或编码。
推荐阅读
- android - 在 Android 应用程序中使用 iBeacons
- c# - c#控制台当前输入值
- javascript - 为什么我的移动导航栏会出现这种情况?
- java - nmap 找不到 nmap 服务
- angular - 如何使用角度 6 在电子应用程序的非活动窗口中呈现更新?
- wordpress - 与 wordpress 和 laravel 混合配置服务器的最佳方法
- java - String.matches(
) 扔东西? - c++ - 基于节点的树结构的 Python 绑定
- sas - 在 SAS 中计算 AVERAGE
- arrays - Vue.js 内联编辑组件在保存前按 lodash 排序