postgresql - sequelize 更新事务锁行

标签 postgresql express transactions sql-update sequelize.js

您好,我正在尝试创建一个队列,以便在有人点击正在使用 sequelize.js 在我的 postgres 数据库上进行更新的 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 Executing (default): UPDATE "lessons" SET "fileWatched"='/Users/Joshua/Desktop/projects/test_watching',"updatedAt"='2017-02-21 03:51:23.132 +00:00' WHERE "id" = '5'

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

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

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

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

1 Executing (7d3b44c1-022d-45b5-a873-d09be8726963): SELECT "id", "name", "lecture", "link", "repo", "fileWatched", "createdAt", "updatedAt", "classId" FROM "lessons" AS "lesson" WHERE "lesson"."id" = '5';

1 Executing (2acc13f0-f351-4c73-b2ee-db1a63c7c460): SELECT "id", "name", "lecture", "link", "repo", "fileWatched", "createdAt", "updatedAt", "classId" FROM "lessons" AS "lesson" WHERE "lesson"."id" = '5';

1 Executing (7d3b44c1-022d-45b5-a873-d09be8726963): UPDATE "lessons" SET "repo"='[{"title":"hahaha","path":"hahaha"}]',"updatedAt"='2017-02-21 03:51:23.189 +00:00' WHERE "id" = '5'

1 Executing (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 Executing (7d3b44c1-022d-45b5-a873-d09be8726963): COMMIT;

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



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

这是我第一次搞乱交易,我似乎找不到很好的文档,对我帮助最大的是
transaction documentation

最佳答案

需要设置 SERIALIZABLE Isolation 来防止这种情况

引用: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.
});

关于postgresql - sequelize 更新事务锁行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42358460/

相关文章:

java - HikariCP 未在 close() 上关闭连接(连接泄漏)

macos - 无法为 Phoenix 运行 postgresql

database - 在数据库中使用继承的优点和缺点是什么

sql - postgresql ,当 null 存在时如何递增

node.js - 通过Node.js中的http.ServerResponse将二进制缓冲区发送到客户端

node.js - Paypal :使用 REST API/Nodejs SDK 的交易历史

javascript - 使用 expressJS 将数据插入到 MongoDB

node.js - 如何在MongoDB中设置缓冲区偏移范围,它不允许在BSON对象中上传超过16MB的文件?

java - Spring Batch - 提交间隔和跳过限制

php - 在 MySQL InnoDB 中取消事务而不是提交或回滚