要确保在共享设置中独占使用Cloud文档,只需读取、然后写入事务中的字段(例如“lockedBy”)就足够了吗?
发布于 2017-10-31 02:44:06
悲观与乐观
中没有原生的独占锁定。由于该系统设计为在大型分布式系统(例如,1000的移动电话用户或Kubernetes集群)中运行,因此它是基于乐观锁定模式的。
这意味着,当您执行读-写事务时,如果您读取的文档在提交事务之前被写入,事务将失败,以便客户端可以回滚。
构建您自己的- Mobile和安全规则
我将假设您是从移动SDK开始的,并将在下一节中处理服务器客户端。
您可以使用单独的文档在此基础上构建独占锁。例如,假设您希望在集合critical_data中实现对文档的独占锁定。
为此,我们将使用一个名为mutex_critical_data的单独集合,其中的文档对于集合critical_data中具有相同id的文档是互斥的。
在访问一个名为doc_id的critical_data文档之前,您需要执行一个写事务来将互斥字段owner设置为您。我假设您使用的是Firebase Auth,因此您可以==用户的auth id auth_id。这可以是唯一标识用户或进程的任何id。
完成文档后,删除互斥文档,以便其他人可以使用它。
为了确保它是独占的,而且其他人不能窃取它,您需要在您的安全规则定义中添加一些检查。
// In the match section that sets the document id to 'doc_id'
function mutex_exists ()
{
return exists(/databases/$(database)/documents/mutex_critical_data/$(doc_id));
}
function mutex_owner ()
{
return get(/databases/$(database)/documents/mutex_critical_data/$(doc_id)).data;
}
function user_owns_mutex () {
return mutex_owner().owner == request.auth.uid;
}
allow write: if not(mutex_exists()) || user_owns_mutex;还可以使用规则强制互斥,也可以通过拥有互斥对象对资源进行预测写入。
构建自己的-服务器客户端
请记住,安全规则是针对Mobile/Web访问的,而不是用于服务器客户端。由于服务器客户端被认为是受信任的环境,而不是由规则强制执行排他性逻辑,因此您需要在互斥对象上的读-写事务中进行检查。
租赁而非锁具
最后一点,如果您构建这一点,我强烈建议您查看独占租约,而不是独占锁。
租约就像一个锁,但是如果租赁者不(或不允许)在规定的时间之前续订租约,它就会自动过期。这意味着,如果客户端不回来(例如,客户端崩溃),其他人最终将能够在不执行管理员操作的情况下获得租约。
这个概念是相同的,但与其只设置所有者,还可以在字段中设置租约时间。如果租约大于旧的x,其中x是租约的时间长度,则考虑不再由所有者持有。在租约到期之前,您可以选择允许所有者通过设置新的租赁时间来续订租约。
发布于 2021-03-23 11:05:40
如果Firestore事务做您想做的事情,您可能根本不需要实现锁。我正在考虑锁定一个文档,以便在更新之前首先检查该文档中的一个字段,但是Firestore允许我锁定文档,这样我就可以读取和更新文档,而无需任何其他进程访问该文档。
发布于 2021-05-30 14:50:50
如果使用Admin (或相应的REST ),全局锁的一个选项是使用创建方法。
..。如果文档在其位置存在,这将导致写入失败。
https://stackoverflow.com/questions/47026295
复制相似问题