Typegoose 管理事务有哪些方式

Typegoose 本身不提供事务管理的功能,它是基于 Mongoose 构建的,因此可以使用 Mongoose 的事务管理功能来管理事务。常用的方式包括:

使用 session 来管理事务。可以在创建 Model 实例时指定 session,所有在该 session 下进行的操作都将参与到该事务中,最终可以通过提交或回滚 session 来管理事务的提交和回滚。


async function createNewUserAndGroup() {
    const session = await startSession(); // 开启会话

    try {
        session.startTransaction(); // 开启事务
        
        const newUser = new UserModel({ // 创建新用户
            name: 'Alice',
            email: 'alice@example.com',
        });

        await newUser.save({session}); // 在事务中保存用户

        const newGroup = new GroupModel({ // 创建新组
            name: 'Admins',
            users: [newUser._id], // 将新用户加入组
        });

        await newGroup.save({session}); // 在事务中保存组

        await session.commitTransaction(); // 提交事务
    } catch (error) {
        await session.abortTransaction(); // 回滚事务
        console.error(error);
    } finally {
        session.endSession(); // 结束会话
    }
}

使用 runInTransaction 静态方法来管理事务。在 runInTransaction 方法中执行的所有操作都将参与到一个新的事务中,如果所有操作都执行成功,则提交事务,否则回滚事务。

import { UserModel } from './UserModel';
import { GroupModel } from './GroupModel';

async function createNewUserAndGroup() {
  await UserModel.runInTransaction(async (session) => {
    const newUser = new UserModel({
      name: 'Alice',
      email: 'alice@example.com',
    });

    await newUser.save({ session });

    const newGroup = new GroupModel({
      name: 'Admins',
      users: [newUser._id],
    });

    await newGroup.save({ session });
  });
}

需要注意的是,如果使用 runInTransaction 方法管理事务,则该方法只能在 Model 类上调用,不能在 Model 实例上调用。