mongoose 在Mongodb事务中使用Promise.all()在Nestjs中无法正常工作

wko9yo5t  于 2023-03-08  发布在  Go
关注(0)|答案(1)|浏览(167)

你好,我在一个使用mongodb和mongoose的NestJS项目工作。
我必须创建内部有很多承诺的事务,所以我认为在事务中使用Promise.all()来解决性能问题是个好主意。
不幸的是,当我开始处理我的事务时,我遇到了第一个问题,我使用的是session.startTransaction();,我的代码引发了以下错误:Given transaction number 2 does not match any in-progress transactions. The active transaction number is 1,有时会抛出错误,但并不总是这样,但这是一个问题
所以我读了下面的问题Mongoose Promise.all() Transaction Error,我开始使用withTransaction(),这解决了问题,但现在mi代码不能正常工作。
代码基本上是接受一个预订数组,然后创建它们,还需要创建预订组合,我需要的是,如果创建预订或组合失败,不应该插入任何内容,为了提高性能,我使用Promise. all()。
但当我执行函数时,有时会创建比预期更多的预订,如果bookingsArray的大小为2,有时会创建3个预订,我只是不知道为什么,这种情况很少发生,但这是一个大问题。
如果我从事务中删除Promise. all(),它将完美地工作,但是如果没有Promise. all(),查询将很慢,所以我想知道我的代码中是否有任何错误,或者您是否无法在Nestjs的mongodb事务中使用Promise. all(
主要功能与事务和Promise. all(),这一个有时会创建错误的预订数量

async createMultipleBookings(
    userId: string,
    bookingsArray: CreateBookingDto[],
  ): Promise<void> {
    const session = await this.connection.startSession();
    await session.withTransaction(async () => {
      const promiseArray = [];
      for (let i = 0; i < bookingsArray.length; i++) {
        promiseArray.push(
          this.bookingRepository.createSingleBooking(
            userId,
            bookingsArray[i],
            session,
          ),
        );
      }
      promiseArray.push(
        this.bookingRepository.createCombosBookings(bookingsArray, session),
      );
      await Promise.all(promiseArray);
    });
    session.endSession();
  }

主要功能与事务和没有Promise. all(),工作正常,但速度慢

async createMultipleBookings(
    userId: string,
    bookingsArray: CreateBookingDto[],
  ): Promise<void> {
    const session = await this.connection.startSession();
    await session.withTransaction(async () => {
      for (let i = 0; i < bookingsArray.length; i++) {
        await this.bookingRepository.createSingleBooking(
          userId,
          bookingsArray[i],
          session,
        );
      }
      await this.bookingRepository.createCombosBookings(bookingsArray, session);
    });
    session.endSession();
  }

在main函数内部调用的函数
一个二个一个一个
这也是我创建连接元素的方法:

export class BookingService {
  constructor(
    @InjectModel(Booking.name) private readonly model: Model<BookingDocument>,
    private readonly authService: AuthService,
    private readonly bookingRepository: BookingRepository,
    @InjectConnection()
    private readonly connection: mongoose.Connection,
  ) {}
uqzxnwby

uqzxnwby1#

我重新编写了整个代码,使用insertMany()而不是使用循环来执行多个单次插入,并删除了mongo事务中的promise.all。

相关问题