pwr*_*ray 4 database locking transactions firebase google-cloud-firestore
要确保在共享设置中独占使用Cloud Firestore文档,是否足以在事务中读取,然后写入字段(例如"lockedBy")?
Dan*_*ath 11
Cloud Firestore中没有本机独占锁定.由于系统设计为在大型分布式系统(例如,1000个移动电话用户或Kubernetes集群)中运行,因此它基于乐观锁定模式.
这意味着当您执行读写事务时,如果您在提交事务之前写入了您读取的文档,则事务将失败,因此客户端可以回滚.
我将假设你是从移动SDK开始进入的,并将在下一节中介绍服务器客户端.
您可以使用单独的文档在此基础上构建独占锁.例如,假设您要对集合中的文档实现独占锁定critical_data
.
为此,我们将使用一个名为的单独集合mutex_critical_data
,其中的文档内部是互斥,用于集合中具有相同id的文档critical_data
.
在您可以访问调用的文档之前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;
Run Code Online (Sandbox Code Playgroud)
您还可以使用规则来强制执行互斥锁,方法是通过拥有互斥锁来预测对资源的写入.
请记住,安全规则适用于Mobile/Web SDK访问,不适用于服务器客户端.由于服务器客户端被视为可信环境,而不是由规则强制执行排他性逻辑,因此您需要在互斥锁上执行读写事务.
最后一点,如果你建立这个,我强烈建议寻找独家租约而不是独家锁.
租约就像锁,但如果租约在规定时间之前没有(或不允许)续租,它会自动到期.这意味着如果客户端没有回来(例如,客户端崩溃),其他人最终将能够在没有管理员操作的情况下获得租约.
概念是相同的,但您不是仅设置所有者,而是在字段中设置租约时间.如果租约大于x
旧x
租约,则租约的时间长度在哪里,业主不再认为.在租约到期之前,您可以选择允许所有者通过设置新的租约时间来续订租约.
归档时间: |
|
查看次数: |
2531 次 |
最近记录: |