我使用 Firebase 事务来获取比较值,然后更新集合中文档的值。
但是当我使用相同的数据并同时发送查询时,它们都读取相同的值,因此我确实通过了两者的检查,并且我最终得到了不好的结果。 该字段递减两次。
我的交易是:
let docRef = db.collection('X').doc('SF');
let reduceValue = 20;
let transaction = db.runTransaction(t => {
return t.get(docRef)
.then(doc => {
let value = doc.data().y ;
if (value >= reduceValue) {
t.update(cptRef, { y:FieldValue.increment(-reduceValue) });
return Promise.resolve('Y increased');
} else {
return Promise.reject('sorry y is ');
}
});
}).then(result => {
console.log('Transaction success', result);
}).catch(err => {
console.log('Transaction failure:', err);
});
谢谢。
如果我正确理解您的问题,您所描述的是使用其中一个 Firestore 客户端 SDK 执行的 Firestore 事务的正确行为:
- 您正在调用两次旨在减少计数器的函数;
- 最后,计数器递减两次。
您的两个调用"同时"执行的事实不应改变结果:计数器应递减两次。
这正是事务所确保的:在并发编辑的情况下,Cloud Firestore 会再次运行整个事务,确保初始文档(在您的情况下db.collection('X').doc('SF')
(在事务期间没有更改。如果是这种情况,它将使用新数据重试操作。
这是因为客户端 SDK 对事务使用乐观并发,因此不会锁定文档。
我建议您观看以下官方视频,其中详细解释了这一点。
您还将在此视频中看到,对于从后端执行的事务(例如使用管理 SDK(,机制并不相同:它们实现悲观并发(在事务期间锁定文档(。