首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >bookshelf.js锁事务

bookshelf.js锁事务
EN

Stack Overflow用户
提问于 2015-07-24 13:56:39
回答 2查看 3.4K关注 0票数 4

是否有可能用书架创建原子数据库事务?我对数据库中的副本有问题。有问题的代码如下:

代码语言:javascript
复制
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秒之间,这几乎不会给我提供重复的时间。但这显然不是一个现成的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-27 10:01:13

好的,最后,我决定使用async.js库,它是队列。队列保证最大n个异步任务同时执行。在本例中,我创建了一个导出队列实例的模块。这样我就可以跨多个模块使用它。它只是等待承诺的实现。

代码语言:javascript
复制
var async = require('async');

module.exports = async.queue(function (task, callback) {
    task().then(function () {
        callback();
    });
},1);

然后,在模块中,我需要一个“原子”事务,我有以下代码:

代码语言:javascript
复制
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});
                }
            });
    });
});

重要的是将事务包装成一个函数,这样它就不会立即被执行。

票数 2
EN

Stack Overflow用户

发布于 2015-07-24 15:28:01

因为书架事务是承诺的,所以不需要显式地调用commit()rollback()。只需履行自己承诺的承诺,否则就可以通过抛出异常来强制回滚。

在您的代码中,显然有一个小错误可能会导致问题:fetch()then()中缺少一个参数--这个参数是fetch()调用的结果,如果找到了对象,则是一个实例,如果没有,则是null

代码语言:javascript
复制
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
});

我现在无法测试它,但我希望它能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31612433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档