繁体   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