sequelize更新事务锁定行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sequelize更新事务锁定行相关的知识,希望对你有一定的参考价值。

你好我试图创建一个队列,当有人在我的postgres数据库上使用sequelize.js进行api路由时,正在进行更新。我的主要目标是防止并发修改一行数据。

addFile(req, res) {
    // repoPath = directory being watched
    // localPath = full local path change was made on
    const { repoPath, localPath, data, className, lessonName, lessonId, classCode } = req.body;
    const { pathToRepoStorage, subPath, fileDirectory } = this.pathMaker(repoPath, localPath, className, lessonName);
    let repo = null;
    return sequelize.transaction((t) => {
      // chain all your queries here. make sure you return them.
      return Lesson.findById(lessonId,
        {
          transaction: t,
        })
      .then((lesson) => {
        repo = lesson.get('repo');
        this.addNodeToTree(repo, fileDirectory, subPath);
        return Lesson.update({ repo },
          {
            where: {
              id: lessonId,
            },
            transaction: t,
          });
      });
    }).then((updated) => {
      // Transaction has been committed
      // result is whatever the result of the promise chain returned to the transaction callback
      if (updated) {
        fs.outputFile(pathToRepoStorage, data, (err) => {
          if (err) {
            res.sendStatus(500);
          } else {
            // send repo object
            this.io.to(classCode).emit('updated-directory', repo);
            res.sendStatus(200);
          }
        });
      } else {
        throw new Error();
      }
    }).catch((err) => {
      // Transaction has been rolled back
      // err is whatever rejected the promise chain returned to the transaction callback
      res.sendStatus(500);
    });
}

我要回的信息是:

1执行(默认):UPDATE“lessons”SET“fileWatched”='/ Users / Joshua / Desktop / projects / test_watching',“updatedAt”='2017-02-21 03:51:23.132 +00:00'WHERE“ id“='5'

1执行(7d3b44c1-022d-45b5-a873-d09be8726963):START TRANSACTION;

1执行(2acc13f0-f351-4c73-b2ee-db1a63c7c460):START TRANSACTION;

1执行(7d3b44c1-022d-45b5-a873-d09be8726963):SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

1执行(2acc13f0-f351-4c73-b2ee-db1a63c7c460):SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

1执行(7d3b44c1-022d-45b5-a873-d09be8726963):SELECT“id”,“name”,“lecture”,“link”,“repo”,“fileWatched”,“createdAt”,“updatedAt”,“classId”从“课程”到“课程”在哪里“课”。“id”='5';

1执行(2acc13f0-f351-4c73-b2ee-db1a63c7c460):SELECT“id”,“name”,“lecture”,“link”,“repo”,“fileWatched”,“createdAt”,“updatedAt”,“classId”从“课程”到“课程”在哪里“课”。“id”='5';

1执行(7d3b44c1-022d-45b5-a873-d09be8726963):更新“课程”SET“repo”='[{“title”:“hahaha”,“path”:“hahaha”}]',“updatedAt”=' 2017-02-21 03:51:23.189 +00:00'WHERE“id”='5'

1执行(2acc13f0-f351-4c73-b2ee-db1a63c7c460):UPDATE“lessons”SET“repo”='[{“title”:“hello”,“path”:“hello”}]',“updatedAt”=' 2017-02-21 03:51:23.189 +00:00'WHERE“id”='5'

1执行(7d3b44c1-022d-45b5-a873-d09be8726963):COMMIT;

1执行(2acc13f0-f351-4c73-b2ee-db1a63c7c460):ROLLBACK;

虽然这确实阻止了我的第二个呼叫覆盖我的第一个呼叫,但我的第二个呼叫完全被忽略,我需要在我的第一个呼叫完成后立即运行。

这是我第一次搞乱交易,我似乎无法找到非常好的文档,它帮助了我最多的是transaction documentation

答案

需要设置SERIALIZABLE隔离以防止这种情况发生

参考:http://docs.sequelizejs.com/en/v3/api/transaction/

return sequelize.transaction({
  isolationLevel: Sequelize.Transaction.SERIALIZABLE
}, function (t) {

 // your transactions

}).then(function(result) {
  // transaction has been committed. Do something after the commit if required.
}).catch(function(err) {
  // do something with the err.
});
另一答案

请阅读链接http://docs.sequelizejs.com/class/lib/transaction.js~Transaction.html您将解决问题

return sequelize.transaction({isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE}, transaction => {

 // your transactions

}).then(result => {
  // transaction has been committed. Do something after the commit if required.
}).catch(err => {
  // do something with the err.
});

以上是关于sequelize更新事务锁定行的主要内容,如果未能解决你的问题,请参考以下文章

提交的Sequelize事务的结果为“未定义”

Sequelize .update() 不使用正确的位置并更新所有行

数据库事务介绍

SQL Server 的 Sequelize 事务隔离级别问题

Access 2007 - “无法更新;当前已锁定”

数据库 锁机制