使用bookshelf.js,如何以原子方式更新模型记录?

时间:2015-08-04 04:17:13

标签: node.js express ejs bookshelf.js

我与JOB模型和许多TASK有一对多的关系。我有一个单独任务的路由,我获取TASK模型进行显示,以及来自其JOB模型的一些数据。当我请求TASK时,我需要更新locked和user_id字段,这样我就可以锁定任务并显示锁定任务的人,这样其他用户就无法访问该任务视图。因此,我需要保证任务已锁定= 0,并立即用时间戳更新该字段。

我当前的路由器代码是:

var route_task = function(req, res, next) {
   new Model.Task({id: req.params.id}).fetch(withRelated: ['jobs']})
      .then(function(task) {
         if (!task) {
            res.status(404);
            res.render('404_tpl');
            return;
         }
         if (task.get('locked') !== 0) {
            res.status(403);
            res.render('403_tpl', {title: '403 - Access Denied - Task is locked'});
            return;
         }
         else {
            /* I would update it here, but there's a slim */
            /* chance someone else can come in and select */
            /* the task. */
         }

         /* .. I set some res.locals vals from my task here .. */

         var jobs = task.related('jobs');
         jobs.fetch().then(function(job) {
            /* .. I set some res.local vals here from my jobs .. */

            switch (task.get('task_type')) {
               case 0:
                  res.render('task_alpha_tpl');
                  break;

               /* ... */
            }
         });
      })
}

当我点击我的路由器获取特定任务ID时,我非常想选择* where tasks.id = id和locked = 0,然后将lock设置为当前时间戳,但是,我需要能够确定如果具有该ID的记录不存在,或者如果存在,但只是被锁定。

我希望这是有道理的。我来自C和PHP世界,所以我慢慢学习异步编程。

2 个答案:

答案 0 :(得分:1)

我认为你应该在一个交易中做到这一点我猜你是否希望价值不要改变,我认为你不应该使用信号量或客户端的其他东西来模拟一个关键部分或者那种心态。

答案 1 :(得分:0)

此问题的一般目的解决方案是以以下形式运行:

UPDATE task SET locked=1,user=? WHERE job=? AND locked=0

然后检查更新是否实际修改了至少一行。 如果你在node.js中这样做,那么我会做类似的事情:

Tasks.forge().where({job: req.param('code'), locked:0}).save({locked:1},{method:"update"});