bookshelf.js 锁定交易
bookshelf.js locking transactions
是否可以使用书架创建原子数据库事务?我在数据库中遇到重复问题。有问题的代码如下:
bookshelf.transaction(function (t) {
var modelLocation = new Models.Location({'name':event.venue});
modelLocation.fetch({transacting:t})
.then(function (fetchedLocation) {
if (!fetchedLocation) {
modelLocation.save(null,{transacting:t}).then(function (savedModel) {
t.commit(savedModel)
}).catch(function (err) {
t.rollback(err)
});
}
else{
t.commit(fetchedLocation)
}
})
})
我几乎同时异步调用了包含这段代码的方法 20 次。在这 20 个中,有 5 个重复的数据集。这会导致数据库中出现大约 2-3 个重复项。当前的解决方法是将整个事情包装在 setTimeout 中,随机超时在 0 到 10 秒之间,这几乎不会给我重复项。但这显然不是一个生产就绪的解决方案。
由于 Bookshelf 交易是承诺,因此您无需显式调用 commit()
或 rollback()
。让已履行的承诺自行提交,或者您可以通过抛出异常强制回滚。
在您的代码中显然有一个可能导致问题的小错误:fetch()
的 then()
中缺少一个参数——这个参数是 [=13 的结果=] 调用,如果找到对象则为实例,否则为 null
。
bookshelf.transaction(function (t) {
var modelLocation = new Models.Location({'name':event.venue});
return modelLocation
.fetch()
.then(function (fetchedLocation) {
if (!fetchedLocation) {
modelLocation
.save(null,{transacting:t});
}
})l
});
我现在无法测试,但希望对您有所帮助。
好的,最后,我决定使用 async.js 库和它的队列。
队列保证最多 n 个异步任务同时执行。在这种情况下 1。
我制作了一个导出队列实例的模块。这样我就可以跨多个模块使用它。它只是等待 promise 实现。
var async = require('async');
module.exports = async.queue(function (task, callback) {
task().then(function () {
callback();
});
},1);
然后在模块中,我需要一个 "atomic" 事务,我有以下代码:
var queue = require('./transactionQueue');
...
...
queue.push(function(){
return bookshelf.transaction(function (t) {
var modelLocation = new Models.Location({'name':event.venue});
return modelLocation
.fetch({transacting:t})
.then(function (fetchedLocation) {
if (!fetchedLocation) {
return modelLocation
.save(null,{transacting:t});
}
});
});
});
将交易包装到一个函数中很重要,这样它就不会立即执行。
是否可以使用书架创建原子数据库事务?我在数据库中遇到重复问题。有问题的代码如下:
bookshelf.transaction(function (t) {
var modelLocation = new Models.Location({'name':event.venue});
modelLocation.fetch({transacting:t})
.then(function (fetchedLocation) {
if (!fetchedLocation) {
modelLocation.save(null,{transacting:t}).then(function (savedModel) {
t.commit(savedModel)
}).catch(function (err) {
t.rollback(err)
});
}
else{
t.commit(fetchedLocation)
}
})
})
我几乎同时异步调用了包含这段代码的方法 20 次。在这 20 个中,有 5 个重复的数据集。这会导致数据库中出现大约 2-3 个重复项。当前的解决方法是将整个事情包装在 setTimeout 中,随机超时在 0 到 10 秒之间,这几乎不会给我重复项。但这显然不是一个生产就绪的解决方案。
由于 Bookshelf 交易是承诺,因此您无需显式调用 commit()
或 rollback()
。让已履行的承诺自行提交,或者您可以通过抛出异常强制回滚。
在您的代码中显然有一个可能导致问题的小错误:fetch()
的 then()
中缺少一个参数——这个参数是 [=13 的结果=] 调用,如果找到对象则为实例,否则为 null
。
bookshelf.transaction(function (t) {
var modelLocation = new Models.Location({'name':event.venue});
return modelLocation
.fetch()
.then(function (fetchedLocation) {
if (!fetchedLocation) {
modelLocation
.save(null,{transacting:t});
}
})l
});
我现在无法测试,但希望对您有所帮助。
好的,最后,我决定使用 async.js 库和它的队列。 队列保证最多 n 个异步任务同时执行。在这种情况下 1。 我制作了一个导出队列实例的模块。这样我就可以跨多个模块使用它。它只是等待 promise 实现。
var async = require('async');
module.exports = async.queue(function (task, callback) {
task().then(function () {
callback();
});
},1);
然后在模块中,我需要一个 "atomic" 事务,我有以下代码:
var queue = require('./transactionQueue');
...
...
queue.push(function(){
return bookshelf.transaction(function (t) {
var modelLocation = new Models.Location({'name':event.venue});
return modelLocation
.fetch({transacting:t})
.then(function (fetchedLocation) {
if (!fetchedLocation) {
return modelLocation
.save(null,{transacting:t});
}
});
});
});
将交易包装到一个函数中很重要,这样它就不会立即执行。