【问题标题】:Add transaction to sequelize create module添加事务以续集创建模块
【发布时间】:2019-07-11 04:14:17
【问题描述】:

我开始使用 sequelize 创建 API,但我遇到了事务问题。

我的 sequelize 数据库配置如下:

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;

然后我有一个库存控制器,其功能可以像这样保存在数据库中:

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) {})...}

我想创建 transaction 以在一个 transaction 中保存到 stockvariant 和 stock 表中,并且可以选择在出错时回滚。

sequelize 中的文档对我来说并不容易理解,因为我不知道如何应用它

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

因为 t 当然没有在任何地方定义,而且我的 stockcontroller 不导入 sequelize。

所以最后我不明白如何定义该交易函数以创建新股票线的基本概念。

感谢您的帮助!

【问题讨论】:

    标签: mysql node.js express sequelize.js


    【解决方案1】:

    sequelize 实例需要被导入才能使用事务。它已经通过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');
    

    现在让我们来谈谈交易。正如documentation 中所述,您有两种处理方式:托管或非托管。

    托管交易

    这是通过在 sequelize 事务回调中链接您的异步操作来完成的。在这种情况下,如果与事务关联的操作成功,则事务将自动提交,否则将回滚。

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

    非托管事务

    如果您希望提高交易透明度和/或控制交易,您可以使用非托管交易。在这种情况下,您必须手动调用commitrollback

    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();
        }
    }
    

    【讨论】:

    • 非常感谢您提供如此有帮助和解释性的回复。现在我懂了! :)
    猜你喜欢
    • 2016-04-16
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 2017-03-30
    • 2023-03-06
    相关资源
    最近更新 更多