是否有可能用书架创建原子数据库事务?我对数据库中的副本有问题。有问题的代码如下:
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秒之间,这几乎不会给我提供重复的时间。但这显然不是一个现成的解决方案。
发布于 2015-07-27 10:01:13
好的,最后,我决定使用async.js库,它是队列。队列保证最大n个异步任务同时执行。在本例中,我创建了一个导出队列实例的模块。这样我就可以跨多个模块使用它。它只是等待承诺的实现。
var async = require('async');
module.exports = async.queue(function (task, callback) {
task().then(function () {
callback();
});
},1);然后,在模块中,我需要一个“原子”事务,我有以下代码:
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});
}
});
});
});重要的是将事务包装成一个函数,这样它就不会立即被执行。
发布于 2015-07-24 15:28:01
因为书架事务是承诺的,所以不需要显式地调用commit()或rollback()。只需履行自己承诺的承诺,否则就可以通过抛出异常来强制回滚。
在您的代码中,显然有一个小错误可能会导致问题:fetch()的then()中缺少一个参数--这个参数是fetch()调用的结果,如果找到了对象,则是一个实例,如果没有,则是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
});我现在无法测试它,但我希望它能有所帮助。
https://stackoverflow.com/questions/31612433
复制相似问题