[英]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.