MongoDB 运行事务

使用 transaction() 函数运行事务

import { Types } from "mongoose";

// 创建会话
const mongoSession = await this.app.mongoose.startSession();
// 开启事务
mongoSession.startTransaction();
try {
    // SQL
    await ctx.model.User.updateOne({
        _id: Types.ObjectId("61c9aca30132f0005b956310"),
    },
    {
        $set: {
            nickname: "user01_updated",
        },
    },
    {
        session: mongoSession,
    });

    // SQL
    await ctx.model.User.updateOne({
        _id: Types.ObjectId("61caa13658a25700628e91d4"),
    },
    {
        $set: {
            nickname: "user02_updated",
            // _id: 'user02_updated', // 错误的写法,_id是ObjectID,所以这条SQL语句不会被执行
        },
    },
    {
        session: mongoSession,
    });
    // do something...

    // 假设这里业务逻辑出现异常,中止此会话中当前活动的事务
    // await mongoSession.abortTransaction();

    // 提交事务
    await mongoSession.commitTransaction();
} catch (err) {
    ctx.logger.error(err);
} finally {
    // 在服务器上结束此会话
    mongoSession.endSession();
}

使用 withTransaction() 函数运行事务

import { Types } from 'mongoose';
import assert = require('assert');

// 创建会话
const conn = ctx.app.mongoose.connection;
const mongoSession = await conn.startSession();
try {
    // 执行事务
    await mongoSession.withTransaction(async () => {
        // SQL
        const user = await ctx.model.User.findById({
            _id: Types.ObjectId('61c9aca30132f0005b956310'),
        }).session(mongoSession);
        // 断言检查
        assert.ok(user.$session());

        // 更新nickname字段值
        user.nickname = 'user01_updated';
        const updateRes = await user.save();

        // 成功则执行后续业务逻辑,失败则中断事务
        if (updateRes) {
            // do something...
        } else {
            await mongoSession.abortTransaction();
        }
    },
    {
        // 读策略
        // 主节点,默认模式,读操作只在主节点,如果主节点不可用,报错或者抛出异常
        readPreference: 'primary',
    });
} catch (err) {
    ctx.logger.error(err);
} finally {
    // 在服务器上结束此会话
    mongoSession.endSession();
}

参考资料

  • https://mongoosejs.com/docs/transactions.html
  • https://mongodb.github.io/node-mongodb-native/3.2/api/ClientSession.html#withTransaction
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值