簡體   English   中英

Flutter 應用程序在雲 Firestore 上執行並發事務時崩潰

[英]Flutter app crashes on concurrent transactions performed on cloud Firestore

我正在嘗試開發一個應用程序,多個用戶可以同時登錄並完成投票。

在此,一旦用戶提交答案,事務就會運行以增加給定答案的計數器

      try {
        DocumentSnapshot freshsnap = await tx.get(reff);
        try {
          await tx.update(reff, <String, dynamic>{
            '$i': freshsnap['$i'] + 1,
          });
        } catch (error) {
          print("Error" + error.code);
        }
      } catch (error) {
        if (error is PlatformException &&
            error.code == 'Error performing transaction') {
          // await tx.set(ref, data);
          print("Error" + error.code);
        } else
          rethrow;
      }
    }).catchError((onError){
      print("Error on: "+onError);
    });

一旦多個用戶同時為同一問題提交相同的答案,即多個用戶同時請求更新同一文檔中的同一字段,應用程序就會崩潰並生成以下錯誤:

FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime(12169): Process: com.rrcg.tumerboared, PID: 12169
E/AndroidRuntime(12169): java.lang.RuntimeException: An error occurred while executing doInBackground()
E/AndroidRuntime(12169):        at android.os.AsyncTask$3.done(AsyncTask.java:354)
E/AndroidRuntime(12169):        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
E/AndroidRuntime(12169):        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
E/AndroidRuntime(12169):        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
E/AndroidRuntime(12169):        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
E/AndroidRuntime(12169):        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(12169):        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(12169):        at java.lang.Thread.run(Thread.java:764)
E/AndroidRuntime(12169): Caused by: java.lang.AssertionError: INTERNAL ASSERTION FAILED: A transaction object cannot be used after its update callback has been invoked.
E/AndroidRuntime(12169):        at com.google.firebase.firestore.util.Assert.fail(com.google.firebase:firebase-firestore@@21.2.1:46)
E/AndroidRuntime(12169):        at com.google.firebase.firestore.util.Assert.hardAssert(com.google.firebase:firebase-firestore@@21.2.1:31)
E/AndroidRuntime(12169):        at com.google.firebase.firestore.core.Transaction.ensureCommitNotCalled(com.google.firebase:firebase-firestore@@21.2.1:246)
E/AndroidRuntime(12169):        at com.google.firebase.firestore.core.Transaction.lookup(com.google.firebase:firebase-firestore@@21.2.1:81)
E/AndroidRuntime(12169):        at com.google.firebase.firestore.Transaction.getAsync(com.google.firebase:firebase-firestore@@21.2.1:191)
E/AndroidRuntime(12169):        at com.google.firebase.firestore.Transaction.get(com.google.firebase:firebase-firestore@@21.2.1:228)
E/AndroidRuntime(12169):        at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$5.doInBackground(CloudFirestorePlugin.java:550)
E/AndroidRuntime(12169):        at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$5.doInBackground(CloudFirestorePlugin.java:545)
E/AndroidRuntime(12169):        at android.os.AsyncTask$2.call(AsyncTask.java:333)
E/AndroidRuntime(12169):        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
E/AndroidRuntime(12169):        ... 4 more

不知道為什么會這樣,因為事務應該允許多個用戶同時更新文檔的字段。

如果你是在物理 iOS 設備上運行,崩潰是由於FlutterFire 綁定庫中的這個錯誤導致的。 似乎沒有解決方法,因此請密切關注該問題以獲取更新。

我通過使事務對象 (tx) 非異步並將異步邏輯移到事務塊之外來解決這個問題。 畢竟,事務的全部意義在於以原子方式執行其指令,而異步指令有點違背了這一目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM