Добавить транзакцию для продолжения создания модуля - PullRequest
0 голосов
/ 17 февраля 2019

Я начинаю с sequelize для создания API и сталкиваюсь с проблемой транзакций.

Моя конфигурация базы данных выглядит так:

var Sequelize = require('sequelize');

var sequelize = new Sequelize(CONFIG.database, env.user, 
 env.password, {
 host: env.host,
 dialect: env.dialect,
 port: env.port,
 operatorsAliases: false
});

var db = {};


fs.readdirSync(__dirname).filter(function (file) {
 return (file.indexOf('.') !== 0) && (file !== 'index.js');
}).forEach(function (file) {
 var model = sequelize.import(path.join(__dirname, file));
 db[model.name] = model;
});

Object.keys(db).forEach(function (modelName) {
 if ('associate' in db[modelName]) {
  db[modelName].associate(db);
 }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

Затем у меня есть stockcontroller с функциями для сохранения в базе данных, например:

var exports = module.exports = {}
let Stock = require('../models').Stock;
let StockVariant = require('../models').StockVariant;

exports.create = function (req, res) {
  const body = req.body;
  console.log(body);
  Stock.create(body).then(function (stock, created) {})...}

Я хочу создать транзакция для сохранения в stockvariant и таблицах запасов в одной транзакции и возможность отката в случае ошибки.

Документация в sequelize не кажется мне легкой дляпонимаю, что я не вижу, как применить это

return sequelize.transaction (function (t) {return User.create ({})})

, потому чтоЭто, конечно, нигде не определено, и мой stockcontroller не импортирует sequelize.

Поэтому, в конце концов, я не понимаю основную концепцию определения этой функции транзакции для создания новой строки запаса.

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 17 февраля 2019

Экземпляру секвелирования необходимо импортировать для использования транзакций.Он уже экспортирован в файл конфигурации базы данных с этой строкой db.sequelize = sequelize.

Все, что вам нужно сделать, это добавить его в текущий импорт:

var exports = module.exports = {}
const Stock = require('../models').Stock; // Prefer const usage to avoid overwritting imports
const StockVariant = require('../models').StockVariant;
const sequelize = require('../models').sequelize;

Это также можно сделать водна строка с использованием деструктуризации:

const { Stock, StockVariant, sequelize } = require('../models');

Теперь давайте перейдем к транзакции.Как указано в документации , у вас есть два способа обработки: управляемый или неуправляемый.

Управляемая транзакция

Это делается путем объединенияасинхронные операции внутри обратного вызова транзакции сиквела.В этом случае, если операции, связанные с транзакцией, завершатся успешно, транзакция будет зафиксирована автоматически, в противном случае произойдет откат.

exports.create = function (req, res) {
    const body = req.body;
    console.log(body);
    sequelize.transaction(function(t) {       
        return Stock.create(body, {transaction: t}) // We pass the transaction as a parameter here !
          .then(function(stock, created) {
               return StockVariant.create(..., {transaction: t}) // The transaction, again here
          })
     .catch(function(err) {
       // Handle your error...
     });  
}

Неуправляемая транзакция

Если вы хотитеДля большей прозрачности и / или контроля над вашей транзакцией вы можете использовать неуправляемую транзакцию.В этом случае вы должны вызвать commit и rollback вручную.

exports.create = function (req, res) {
    const body = req.body;
    console.log(body);
    sequelize.transaction
     .then(function(t) { // Note the 'then' usage here
        return Stock.create(body, {transaction: t}); // We pass the transaction as a parameter here !
          .then(function(stock, created) {
               return StockVariant.create(..., {transaction: t}); // The transaction, again here
          });
     .then(function() {
         return t.commit();
     })
     .catch(function(err) {
         return t.rollback();
     });  
}

Это также можно сделать с помощью синтаксиса async / await, который может быть более приятным для чтения:

exports.create = function (req, res) {
    const body = req.body;
    console.log(body);
    let t; // The variable in which the transaction object will be stored
    try {
        t = await sequelize.transaction();
        const stock = await Stock.create(body, {transaction: t})
        await StockVariant.create(..., {transaction: t}) // Whatever parameter you need to pass here
        await t.commit();
    } catch (err) {
        await t.rollback();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...