[英]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事務是promise,因此您不需要顯式調用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
});
我現在無法測試,但我希望它有所幫助。
好的,最后,我決定使用async.js庫和它的隊列。 隊列保證同時執行最多n個異步任務。 在這種情況下1.我創建了一個導出隊列實例的模塊。 這樣我就可以在多個模塊中使用它。 它只是等待承諾履行。
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});
}
});
});
});
將事務包裝到函數中非常重要,因此不會立即執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.