Prisma transaction – Prisma

by
Alexei Petrov
angular-forms next.js node.js prisma

Quick Fix: Instead of utilizing .forEach, employ ‘for…of’ loops to iterate over ‘variant.photos’ and guarantee proper execution of ‘await’ statements within the loops, ensuring the transaction awaits the completion of all asynchronous operations before closing.

The Problem:

In a Prisma transaction involving upserting a product variant along with its associated photos, the code returns an error message indicating that the transaction is already closed. The goal is to ensure successful upsertion of both the product variant and its photos within a single transaction to maintain data integrity. How can this error be resolved or an alternative approach be taken to achieve the desired result?

The Solutions:

Solution 1: Using for…of loops

The idea is to replace the .forEach loops with for…of loops to ensure that the await statements within the loops are awaited properly. This ensures that the transaction waits for all the asynchronous operations/callbacks to finish before it’s closed. Here’s the modified code:

“`js
return ctx.prisma.$transaction(async (tx) => {
for (const variant of input.variants) {
const variantOnDB = await tx.productVariant.upsert({
where: {
id: variant.id,
},
update: {
name: variant.name,
},
create: {
name: variant.name,
productId: product.id,
},
})

if (variant.photos) {
  for (const photo of variant.photos) {
    if (isBase64(photo.id)) {
      const result = await cloudinary.uploader.upload(photo.id)
      await tx.productVariant.update({
        where: {
          id: variantOnDB.id,
        },
        data: {
          name: '',
          photos: {
            upsert: {
              where: {
                id: photo.id,
              },
              create: {
                id: photo.id,
                order: photo.order,
              },
              update: {
                order: photo.order,
              },
            },
          },
        },
      })
    }
  }
}

}
})

Q&A

What is the cause of the error message "Transaction already closed: Could not perform operation." ?

When using .forEach to iterate over an array and perform async operations, it doesn’t wait for each one to complete before moving on.

How to fix the error message "Transaction already closed: Could not perform operation."?

Replace the .forEach loops with for…of loops to ensure that the await statements within the loops are awaited properly.

Video Explanation:

The following video, titled "Interactive Transactions in Prisma - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Check out the full course at: https://howtoprisma.com/production-ready-prisma/ Prisma offers two ways to do transactions: sequential ...