【问题标题】:How to use transaction by sequelize in my node js如何在我的节点 js 中通过 sequelize 使用事务
【发布时间】:2018-05-18 20:06:16
【问题描述】:

在将旧的长 sql 过程转换为 sequelizer 时,我遇到了对我的异步函数进行事务处理的麻烦。

我阅读了 sequelizer 的交易文件。但是没看清楚。

这是我的代码。

const models = require('../models/models.js');
const sequelize = models.Sequelize;


async function isExistFeeHist(dansokSeqNo) {
  log.debug("isExistFeeHist()");
  let feeHist = await models.FeeHist.findOne({  
    where: { 
      DansokSeqNo: dansokSeqNo,
      FeeStatus: {[Op.ne]: null}, //is not null
      DelYN: false
    }
  });
  return !!feeHist;
}

async function isPaid(dansokSeqNo) {
  ...
}

async function getNextDansokHistSerialNo(dansokSeqNo) {
  ...
}

async function getVBankSeqNo(dansokSeqNo) {
  ...                
}

async function updateVBankList(dansokSeqNo, vBankSeqNo) {
  ...
}

//check if can cancel
async function checkCancelable(dansokSeqNo) {
  log.debug("checkCancelable() ", dansokSeqNo);

  if (await isExistFeeHist(dansokSeqNo)) {
    let e = {status:400, message: 'already imposed dansokSeqNo ' + dansokSeqNo };
    return Promise.reject({status:400, message: e.message });
  }

  if (await isPaid(dansokSeqNo)) {
    let e = {status:400, message: 'already paid dansokSeqNo ' + dansokSeqNo };
    return Promise.reject({status:400, message: e.message });
  }

  return Promise.resolve();
}

....

async function doCancel(dansokSeqNo, cancelCauseCode, histMemo) {

  try {
    await checkCancelable(dansokSeqNo); 

    //// <== Here I want to start transaction

    let nextDansokSerialNo =  await getNextDansokHistSerialNo(dansokSeqNo);
    let dansokHist = await insertNewDansokHist(dansokSeqNo, nextDansokSerialNo, cancelCauseCode, histMemo);
    await updateDansokHist(dansokSeqNo, cancelCauseCode);
    let vBankSeqNo = await getVBankSeqNo(dansokSeqNo);
    if (vBankSeqNo > 0) {
      await updateVBankList(dansokSeqNo, vBankSeqNo);
      let vBankList = await getVBankList(dansokSeqNo);
    }

    // <== Here I want to commit transaction
  } catch (e) {
    // <== Here I want to rollback transaction
    return Promise.reject({status:e.status, message: e.message });
  }
}

exports.cancelDansok = function (req, res) {
  res.setHeader("Content-Type", "application/json; charset=utf-8");
  ...
  jwtAcessAuth(accessToken)
  .then((decoded) => {
    log.info("jwt success, ", decoded);
    worker = decoded.loginName;
    return doCancel(dansokSeqNo, cancelCauseCode, histMemo);
  })
  .then(() => {
    res.status(200).json({ message: 'cancelDansok success.' });
  })
  .catch(e => {
    return res.status(e.status).json(e);
  });
};

我的函数由几个异步函数组装而成。并且需要绑定一笔交易。

在我的几个异步等待函数中使用事务的最佳做法是什么?

【问题讨论】:

    标签: sql node.js transactions sequelize.js


    【解决方案1】:

    这是 Sequlize 为 Transaction 提供的最佳示例:

    您只需将transaction 传递到下一级链接

    return sequelize.transaction(function (t) {
    
      // chain all your queries here. make sure you return them.
      return User.create({
        firstName: 'Abraham',
        lastName: 'Lincoln'
      }, {transaction: t}).then(function (user) {
        return user.setShooter({
          firstName: 'John',
          lastName: 'Boothe'
        }, {transaction: t});
      });
    
    }).then(function (result) {
      // Transaction has been committed
      // result is whatever the result of the promise chain returned to the transaction callback
    }).catch(function (err) {
      // Transaction has been rolled back
      // err is whatever rejected the promise chain returned to the transaction callback
    });
    

    更多详情:Transactions

    【讨论】:

    • 为什么一开始就返回?
    • (可能会产生误导)。 sequelize.transaction 返回一个承诺。在上面的 sn-p 中,它是自动管理的形式。如果它解决(然后)然后它被提交,如果不是(拒绝)[catch] 然后它被回滚。上面的回报没有任何意义。除非我们想按照在函数中进行交易来传递承诺。然后我们使用这个函数,或者导出它......等等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    • 2018-07-30
    • 2020-08-14
    • 2020-03-21
    相关资源
    最近更新 更多