下面的代码显示了我们看到错误的最小示例。正如您所看到的,当事务更新test/channels/sameKey/chats/${key}
时,扇出test/user_phone_numbers/${key}
。
如果我理解事务并正确更新,这两个不重叠,因此并发运行应该是安全的。但是,只要有两个并发请求进入,Firebug就会出错[Error: set]
。
'use strict';
const express = require('express');
const server = express();
const firebaseRootRef = new Firebase(process.env.FIREBASE_URL)
const random = max => Math.floor(Math.random() * max)
let key = 0
const nextKey = () => ++key % 2
const fanout = key => {
const fanout = {
[`test/channels/sameKey/chats/${key}`]: random(1000)
}
return firebaseComponent.update(firebaseRootRef, fanout)
}
const transaction1 = key => firebaseRootRef.child('test/user_phone_numbers/' + key)
.transaction(_userId => !_userId ? random(100000) : undefined)
server.get('/', (req, res) =>
transaction1(nextKey())
.then(() => fanout(key))
.then(() => res.send(200))
.catch(e => {console.log(e); res.send(501)})
)
server.listen(3001, function () {
console.log('incoming.controller listening on port 3001!');
});
要复制的apache基准测试命令:
ab -n 1000 -c 2 -r http://localhost:3001/
答案 0 :(得分:1)
这不是一个错误,它按预期工作。几个月前我遇到了这个问题,这是他们给我的官方回应(强调我的)。
此处的问题是与更新调用相结合的事务。 我们将在任何集合中的路径上,下方或上方中止任何交易 更新电话。因此,虽然交易在技术上不受影响 你的更新电话在/ venues / 1,我们仍然继续取消 交易。我们知道这不是最佳的,我们正在研究 通过将来的版本改进这一点。一个解决方法是推迟 更新呼叫,直到交易完成,或保持 完全不同的子树中的数据。最简单的解决方法 可能是将更新调用中的所有写入移动到单独的集合中 电话,不会中止交易。