Google Firebase交易不可靠 [英] Unreliable Google Firebase transactions

查看:80
本文介绍了Google Firebase交易不可靠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的模型(大大简化了)中,我有用户,帐户和account_types。每个用户可以具有每个account_type的多个帐户。创建了TT类型的帐户后,我正在更新该对象的用户字段,以便保留具有该类型帐户的用户以及他们拥有的此类帐户的数量。

In my (greatly simplified) model I have users, accounts and account_types. Each user can have multiple accounts of each account_type. When an account of type TT is created I'm updating the "users" field of that object so it keeps the users which have accounts of that types, and the number of such accounts they have.

users: {
  some fields
},
accounts: {
  userID: UU,
  type: TT
},
account_type: 
  users: { UU: 31 }
}

我使用onCreate和onDelete云触发器为帐户更新account_type对象。由于可以同时创建多个帐户,因此我必须使用事务:

I use the onCreate and onDelete cloud triggers for accounts to update the account_type object. Since multiple accounts can be created simultaneously I have to use transactions:

exports.onCreateAccount = functions.firestore
    .document('accounts/{accountID}')
    .onCreate((account, context) => {
      const acc_user = account.data().userID;
      const acc_type = account.data().type;
      return admin.firestore().runTransaction(transaction => {
        // This code may get re-run multiple times if there are conflicts.
        const accountTypeRef = admin.firestore().doc("account_types/"+acc_type);
        return transaction.get(accountTypeRef).then(accTypeDoc => {
          var users = accTypeDoc.data().users;
          if (users === undefined) {
            users = {};
          }
          if (users[acc_user] === undefined) {
            users[acc_user] = 1;
          } else {
            users[acc_user]++;
          }
          transaction.update(accountTypeRef, {users: users});          
          return;
        })
      })
      .catch(error => {
        console.log("AccountType create transaction failed. Error: "+error);
      });
    });

在我的测试中,我首先用一些数据填充数据库,还添加了一个用户和30个相同类型的帐户。使用本地仿真器可以正常工作,并且在添加结束时,我看到account_type对象包含计数器为30的用户。但是当部署到Firebase并运行相同的功能时,计数器小于30。我的怀疑因为Firebase的速度慢得多,并且交易花费的时间更长,所以更多的交易会相互冲突并失败,最终根本无法执行。交易失败文档( https://firebase.google.com/docs/firestore / manage-data / transactions )说:

In my tests I'm first populating the database with some data so I'm also adding a user and 30 accounts of the same type. With the local emulator this works just fine and at the end of the addition I see that the account_type object contains the user with the counter at 30. But when deployed to Firebase and running the same functions the counter gets to less than 30. My suspicion is that since Firebase is much slower and transactions take longer, more of them are conflicted and fail and eventually don't execute at all. The transaction failure documentation (https://firebase.google.com/docs/firestore/manage-data/transactions) says:


该事务读取了在事务外部修改的文档。在这种情况下,事务将自动再次运行。事务将重试有限次。

"The transaction read a document that was modified outside of the transaction. In this case, the transaction automatically runs again. The transaction is retried a finite number of times."

所以我的问题:


  1. 有限是什么意思?

  2. 有什么方法可以控制这个数字?

  3. 如何确保我的交易在某个时刻执行并且不会丢失,以使我的数据保持一致?

  4. 其他任何东西关于为什么在部署到云时无法获得正确结果的想法?

  1. What does "finite" mean?
  2. Any way to control this number?
  3. How can I make sure my transactions are executed at some point and don't get dropped like that so my data is consistent?
  4. Any other idea as to why I'm not getting the correct results when deployed to the cloud?


推荐答案


有限是什么意思?

What does "finite" mean?

与无限相反。它将重试不超过设定的次数。

It's the opposite of "unlimited". It will retry no more than a set number of times.


有什么方法可以控制这个数字?

Any way to control this number?

除了修改SDK的源代码外,否。 SDK本身会公布一个特定的数字,因为它可能会更改。

Other than modifying the source code of the SDK, no. The SDK itself advertise a specific number, as it might change.


我如何确保我的交易在某个时刻执行,并且不这样做?不会那样丢失,以便我的数据保持一致?

How can I make sure my transactions are executed at some point and don't get dropped like that so my data is consistent?

检测错误并在您的应用中重试。如果您没有看到事务因错误而失败,那么什么都没出错。

Detect the error and retry in your app. If you aren't seeing the transaction fail with an error, then nothing went wrong.


关于我为什么没有的任何其他想法

Any other idea as to why I'm not getting the correct results when deployed to the cloud?

由于无法看到触发该功能的确切作用,并且没有具体的预期结果可比,这真的不可能说。

Since we can't see what exactly you're doing to trigger the function, and have no specific expected results to compare to, it's not really possible to say.

这篇关于Google Firebase交易不可靠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆