簡體   English   中英

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事務是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM