前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Sequelize事务处理回滚失败

Sequelize事务处理回滚失败

作者头像
用户6256742
发布2022-09-16 10:47:13
7530
发布2022-09-16 10:47:13
举报
文章被收录于专栏:网络日志网络日志

如果你使用了MySQL:MyISAM不支持事务处理,请换成InnoDB!!!

在使用Node.js进行服务端开发中我们经常使用Sequelize作为ORM框架,我们对多个数据表进行处理时通常会使用事务处理。在Sequelize事务文档中给了很多方式,主要分为托管和非托管,很多时候我们在回滚时常常发生失败,明明自己以及提交回滚了,但是仍然有数据表被改动了。

下面是我项目中的一个Demo,在tag表删除数据时,对article表中的tag进行置换,如果置换失败则事务回滚取消删除。在置换时我对id进行了+11,使得触发回滚进行测试。

代码语言:javascript
复制
import Router from "@koa/router";
import DB from "@/db";
import sequelize from "@/db/config";
import { Op } from "sequelize";

let router = new Router();

router.delete("/tag/:id", async ctx => {
  let { id } = ctx.params;
  const t = await sequelize.transaction();
  let deleteTagCount = await DB.Tag.destroy({
    where: {
      id: id,
    },
    transaction: t,
  });
  // todo 解决事务处理问题
  /** 需要删除的个数*/
  let { count: tagCount } = await DB.Article.findAndCountAll({
    where: { tag: { [Op.substring]: id } },
  });
  //将文章表中的 ,id,  ,id   id,   id  四种方法全部置换  // +11使得置换失败,触发回滚
  let replaceTagIdResult = await Promise.all<any>([
    sequelize.query(
      `update article set tag=REPLACE (tag,',${id + "11"},',',') WHERE tag like '%${id}%'`,
      { transaction: t }
    ),
    sequelize.query(
      `update article set tag=REPLACE (tag,',${id + "11"}','') WHERE tag like '%${id}%'`,
      { transaction: t }
    ),
    sequelize.query(
      `update article set tag=REPLACE (tag,'${id + "11"},','') WHERE tag like '%${id}%'`,
      { transaction: t }
    ),
    sequelize.query(
      `update article set tag=REPLACE (tag,'${id + "11"}','') WHERE tag like '%${id}%'`,
      { transaction: t }
    ),
  ]).then(res => {
    // 实际删除了多少
    let _tagCount = res.reduce((total, item) => {
      return total + item[0].affectedRows;
    }, 0);
    if (_tagCount != tagCount) {
      console.log(`删除 ${id} 时 置换数量对不上${_tagCount}/${tagCount}`);
      return false;
    } else {
      return true;
    }
  });
  
  if (!(deleteTagCount && replaceTagIdResult)) {
    console.log("回滚");
    ctx.body = {
      success: false,
      message: "删除失败",
    };
    await t.rollback();
  } else {
    ctx.body = {
      success: true,
      message: "删除成功",
    };
    await t.commit();
  }
});
export default router;

当然了,具体在Sequelize中使用事务处理的方法请在文档看,我这里也不说什么代码错误。

我在项目中也遇到了问题解决了好久:MyISAM不支持事务处理,请换成InnoDB

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档