Search code examples
typescriptnestjsprisma

Can not update records using transaction in prisma


I get ids in array from params and I should udpate credential of records with specific ids. The thing is that if record is not found, then the transaction should rollback. This is what i did:

     await this.prisma.$transaction( async () => {
        for(let id of ids) {
          // get category from db
          const category = await this.prisma.category.findFirst({
            where: { id: +id, deleted_at: null },
          });

          // check if exists
          if (!category) {
            throw new BadRequestException({
                status: 400,
                error: true,
                message: 'Category is not found',
            });
          }
          // soft delete from db
          await this.prisma.category.update({
            where: { id: +id },
            data: { deleted_at: new Date() },
          });
        }
      })

Even I throw an Error when record is not found, other records are updated.

The second way I did is:

     await this.prisma.$transaction(
          ids.map(id => this.prisma.category.update({
                where: { id: +id },
                data: { deleted_at: new Date() },
          })
      ));

In this case, if record is not found, I got such error:

Invalid this.prisma.category.update() invocation in\n/files/src/category/category.service.ts:177:46\n\n 174 }\n 175 \n 176 await this.prisma.$transaction(\n→ 177 ids.map(id => this.prisma.category.update(\nAn operation failed because it depends on one or more records that were required but not found. Record to update not found

But in this case, also other records are update! What should I do in this case?

Any help is appreciated :)


Solution

  • See Interactive Transactions

    The first argument passed into this async function is an instance of Prisma Client. Below, we will call this instance tx. Any Prisma call invoked on this tx instance is encapsulated into the transaction.

    You need to make your calls on the client instance passed to the function.

    For example

    await this.prisma.$transaction(async (tx) => {
      const category = await tx.category.findFirst({ // 👈 `tx`, not `this.prisma`
        where: { id: +id, deleted_at: null },
      });
    
      // etc
    });