Android Kotlin中Firestore事务设置最大尝试次数遇问题求助
问题:Firestore事务设置最大尝试次数+避免重复更新(Android Kotlin)
场景说明
- 两台Android设备操作Firestore同一份文档:设备A给
test字段数值加40,设备B加30 - 当前通过事务实现更新,但无法成功设置事务最大尝试次数,同时担心出现重复更新的异常情况
现有事务代码
设备A代码
authFireStore.runTransaction { transaction -> var docRef = refCacheTransaction.collection("test").document("doc") var dataDoc = transaction.get(docRef) updateMap.put("test", (dataDoc.get("test") as Long + 40)) // 字段数值加40 transaction.update(docRef, updateCacheDBDataCollection) return@runTransaction null }
设备B代码
authFireStore.runTransaction { transaction -> var docRef = refCacheTransaction.collection("test").document("doc") var dataDoc = transaction.get(docRef) updateMap.put("test", (dataDoc.get("test") as Long + 30)) // 字段数值加30 transaction.update(docRef, updateCacheDBDataCollection) return@runTransaction null }
尝试过的报错代码
// 尝试用TransactionOptions设置最大尝试次数,但代码报错 TransactionOptions.Builder().setMaxAttempts(5) // 设置事务尝试次数为5 authFireStore.runTransaction(TransactionOptions, Transaction.Function { var docRef = refCacheTransaction.collection("test").document("doc") var dataDoc = it.get(docRef) it.update(docRef, updateCacheDBDataCollection) return null })
解决方案
1. 正确设置事务最大尝试次数
Android Firestore SDK中,TransactionOptions需要先构建实例再传入runTransaction方法,修正后的代码如下:
// 构建事务配置,设置最大尝试次数 val transactionOptions = TransactionOptions.Builder() .setMaxAttempts(5) .build() authFireStore.runTransaction(transactionOptions) { transaction -> val docRef = refCacheTransaction.collection("test").document("doc") val dataDoc = transaction.get(docRef) // 处理字段可能为null的情况,默认值设为0 val currentTestValue = dataDoc.getLong("test") ?: 0 // 直接在事务内计算并更新,依赖外部map会导致重试时数据异常 transaction.update(docRef, "test", currentTestValue + 40) null // 事务返回值,无需要返回数据时传null }.addOnSuccessListener { // 事务成功后的逻辑 }.addOnFailureListener { exception -> // 事务失败(超过尝试次数或其他错误)的处理逻辑 }
2. 彻底避免重复更新的优化方案
如果只是简单的数值累加场景,推荐使用Firestore原生的原子递增方法,无需手动编写事务,Firestore会自动处理并发冲突,保证最终数值是正确的累加结果:
// 设备A的原子更新代码 val docRef = refCacheTransaction.collection("test").document("doc") docRef.update("test", FieldValue.increment(40)) .addOnSuccessListener { // 更新成功逻辑 } .addOnFailureListener { exception -> // 更新失败逻辑 } // 设备B的原子更新代码,替换40为30即可
这种方式比手动事务更简洁,且天然避免了并发场景下的重复更新问题,最终test字段的数值会准确累加为70。
内容的提问来源于stack exchange,提问作者muhammed koç
相关产品推荐
相关产品推荐

