You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js微服务跨服务事务处理:创建用户失败时回滚Person记录

跨服务事务实现:创建User失败时回滚已创建的People记录

你的场景是两个服务分别操作数据库:test2服务创建People记录,test服务创建关联该People的User记录,要求User创建失败时,已创建的People能被回滚。但现有代码存在关键问题,导致无法实现预期的回滚效果。

现有代码的问题

test2服务在创建People后直接执行了await t.commit(),这会导致People记录被立即提交到数据库。后续即使test服务创建User失败并触发回滚,已经提交的People记录无法被撤销——因为事务一旦提交就无法回滚。

修正方案

要实现跨服务的事务一致性,必须由事务的发起方(test服务)统一控制事务的提交和回滚,子服务(test2)只在该事务上下文内执行操作,不自行提交事务。

修正后的test服务代码

async test(req, res) {
    let t = await sequlize.transaction();
    try {
        let rs = await this.getEurekaManager('education');
        const instance = this.createAxiosInstance(req.payload);
        // 传递事务ID给test2服务
        let response = await instance.post(rs.homePageUrl + '/api/v1/TermLessons/test2', {
            firstName: "John",
            lastName: "Doe"
        }, {headers: {'Transaction-Id': t.id}});
        let person = response.data;
        
        // 在同一事务下创建User
        await model.Users.create({
            Username: "johnDoe",
            PersonId: person.PersonId
        }, {transaction: t});
        
        // 所有操作成功后,统一提交事务
        await t.commit();
        res.json("Successfully");
    } catch (error) {
        console.log(error);
        // 任意步骤失败,回滚整个事务(包括test2创建的People)
        await t.rollback();
        res.json(error);
    }
}

修正后的test2服务代码

async test2(req, res) {
    try {
        // 根据传入的事务ID获取已存在的事务对象,而非新建
        let t = await sequlize.transaction({id: req.headers['transaction-id'], lock: true});
        let person = await model.People.create({
            FirstName: req.body.firstName,
            LastName: req.body.lastName
        }, {
            returning: true,
            transaction: t
        });
        // 不要在此处提交事务,由发起方test服务统一控制
        res.json(person);
    } catch (error) {
        console.log(error);
        // 此处无需自行回滚,由发起方统一处理
        res.status(500).json(error);
    }
}

关键说明

  • 事务的生命周期完全由发起方test服务管理:从创建事务,到协调子服务操作,最后统一提交或回滚。
  • test2服务仅在传入的事务上下文内执行创建操作,不提交事务,确保所有操作处于同一个事务边界内。
  • 当test服务中任何一步(调用test2、创建User)失败,都会触发整个事务的回滚,包括test2服务创建的People记录。

内容的提问来源于stack exchange,提问作者mohammad tavassolian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:57:56