首页 > 解决方案 > 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我在这里遇到了类似的问题,但没有帮助。如果有人可以指导我一点,我将不胜感激。

Firestore如何停止Transaction?

标签: androidkotlingoogle-cloud-firestoretransactions

解决方案


是的 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()

在这种情况下,您将直接获得所需的文档。此操作的成本将等于查询返回的文档数。


推荐阅读