android - Android:如何停止 Firestore 交易?
问题描述
首先,我使用它查询 Firestore 中的一些文档queryWaitingRoom()
并调用runTransactionInWaitingRoom()
结果是否满足条件。
这是第一个功能:
private fun queryWaitingRoom() {
waitingRoomRef
.orderBy("isAvailable", Query.Direction.DESCENDING)
.limit(1)
.get()
.addOnSuccessListener { documents ->
if (!documents.isEmpty){
for (document in documents) {
val waitingRoomId = document.get("id").toString()
runTransactionInWaitingRoom(waitingRoomId)
}
}
}
}
我的问题是,runTransactionInWaitingRoom()
如果值currentState
不等于true
,我该如何transaction
在块中停止右边else
?并queryWaitingRoom()
再次调用?这是第二个功能:
private fun runTransactionInWaitingRoom(waitingRoomId: String){
val docRef = waitingRoomRef.document(waitingRoomId)
db.runTransaction { transaction ->
val snapshot = transaction.get(docRef)
val currentState = snapshot.getBoolean("isAvailable")
if (currentState == true){
transaction.update(docRef, "isAvailable", false)
} else {
///// STOP THE TRANSACTION RIGHT HERE /////
///// And call the the queryWaitingRoom() again /////
Log.d("OIWENCLKSJF", "Transaction.currentState != true") // getting called 5 or 6 times.
throw FirebaseFirestoreException("Population too high", // only get called at the last attemp.
FirebaseFirestoreException.Code.ABORTED)
}
}.addOnSuccessListener {
}.addOnFailureListener { e ->
Log.w("OIWENCLKSJF", "Transaction failure.", e)
}
}
到目前为止,我得到的是,transaction
即使我把它扔进街区exception
,它也会不断地调用自己。else
我在这里遇到了类似的问题,但没有帮助。如果有人可以指导我一点,我将不胜感激。
解决方案
是的 isAvailable 属性来自同一个文档。
如果两个属性都在同一个文档中,那么只有当isAvailable
属性的值为 true 时才运行事务:
if (!documents.isEmpty){
for (document in documents) {
val waitingRoomId = document.get("id").toString()
val isAvailable = document.getBoolean("isAvailable")
if(isAvailable) {
runTransactionInWaitingRoom(waitingRoomId)
}
}
}
该解决方案背后的想法是仅在isAvailable
为真时才运行事务。你现在在做什么,你总是在运行事务,在里面,如果条件不成立,取消事务。为什么这个解决方案不可行?假设您有 1 MIL 文档,其中只有 1 是isAvailable
真实的,您是否愿意为了一份文档而运行 1 MIL 事务?恐怕你不是。请记住,在 Firestore 中,执行的每个文档读取都需要一次读取操作。
更好的解决方案是直接在数据库中查询isAvailable
属性值为 true 的文档:
waitingRoomRef
.whereEqualTo("isAvailable", true) //Added
.orderBy("isAvailable", Query.Direction.DESCENDING)
.limit(1)
.get()
在这种情况下,您将直接获得所需的文档。此操作的成本将等于查询返回的文档数。
推荐阅读
- reactjs - 如何将状态传递给 firebaseConnect 中的 doc 属性
- c# - 是否可以在不修改基类的情况下从派生类中更改基类方法中使用的类型?
- c# - 如何按聚合分组?
- file - 如何将 iTextSharp.text.Image 保存到文件
- babeljs - babel 无法解析表达式 `{ display: 'block',}`
- authentication - 在 ASP 中分离前端和后端服务身份验证。网络核心
- php - php脚本更新数据库以匹配数量,而不是添加到它
- button - 我如何防止在表单提交 Angular 7 上重新加载页面
- node.js - 如何使用 officegen 和 Angular 应用程序生成 Word 文档?
- c - RDTSC 和系统调用,sys_read 和 sys_write