2017-02-21 63 views
0

привет Я пытаюсь создать очередь, когда кто-то попадает на маршрут api, который делает обновление, используя sequelize.js на моем postgres db. Моя главная цель - предотвратить одновременную модификацию ряда данных.sequelize update transaction lock row

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 "уроки" SET " fileWatched" = '/ Users/Joshua/Desktop/проекты/test_watching' , "updatedAt" = '2017-02-21 03: 51: 23,132 +00: 00', где "ID" = '5'

1 Выполнение (7d3b44c1-022d-45b5-a873-d09be8726963): START СДЕЛКА;

1 Выполнение (2acc13f0-f351-4c73-b2ee-db1a63c7c460): START TRANSACTION;

1 Выполнение (7d3b44c1-022d-45b5-a873-d09be8726963): УСТАНОВКА ЗАСЕДАНИЯ УРОВЕНЬ ОПАСНОСТИ ИЗОЛЯЦИИ ПОВТОРНОЕ ПРОЧИТАНИЕ;

1 Выполнение (2acc13f0-f351-4c73-b2ee-db1a63c7c460): УСТАНОВКА ЗАСЕДАНИЯ УРОВЕНЬ ОПАСНОСТИ ИЗОЛЯЦИИ ПОВТОРНОЕ ПРОЧИТАНИЕ;

1 Выполнение (7d3b44c1-022d-45b5-a873-d09be8726963): SELECT "ID", "название", " лекцию", "связь", "репо", "fileWatched", "createdAt", " updatedAt "," classId "FROM" уроки "AS" урок "WHERE" урок "." id " = '5';

1 Выполнение (2acc13f0-f351-4c73-b2ee-db1a63c7c460): SELECT "ID", "название", "лекции", "связь", "репо", "fileWatched", "createdAt", " updatedAt "," classId "FROM" уроки "AS" урок "WHERE" урок "." id " = '5';

1 Исполнительные (7d3b44c1-022d-45b5-a873-d09be8726963): UPDATE "уроки" SET "репо" = '[{ "название": "хахаха", "путь": "хахаха"}] , "updatedAt" = '2017-02-21 03: 51: 23,189 +00: 00', где "ID" = '5'

1 Выполнение (2acc13f0-f351-4c73-b2ee-db1a63c7c460): UPDATE " уроки " 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

ответ

0

нужно установить SERIALIZABLE Изоляция для предотвращения этой

Ref: 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. 
}); 
+0

поэтому я попробовал все 3 ISOLATION_LEVELS. По умолчанию «REPEATABLE_READ» сначала проходит второй, после чего возвращается. «READ UNCOMMITTED» они оба фиксируются, но второй переопределяет первый «READ COMMITTED» так же, как и прочитано нефиксировано «SERIALIZABLE», как и для повторного считывания –