Is it bad to include a different database call in a MongDB transaction?

I run a transaction on MongoDB but also include a Pinecone operation in this transaction. I’m aware that Pinecone will not be rolled back if the transaction fails. But this is why I made Pinecone the last operation in the transaction. If Pinecone fails, MongoDB is rolled back. If MongoDB fails, we don’t even reach the execution if Pinecone.

This this fine or should I not do this?

Here is the code. I’m using the Prisma ORM to execute my MongoDB transaction:

  const newEntry = await prisma.$transaction(async (tx) => {
      // MongoDB operations
      if (draft) {
        if (session.user.id !== draft?.userId) throw Error("Not authorized");
        await tx.diaryEntryDraft.delete({ where: { id: draft?.id } });
      }

      const newEntry = await tx.diaryEntry.create({
        data: entryData,
      });

      // Pinecone operation
      await diaryEntriesIndex.upsert([
        {
          id: entryId,
          values: embedding,
          metadata: { userId: session.user.id },
        },
      ]);

      return newEntry;
    });

Hi @Florian_Walther, what’re you describing sounds to what I would consider a nested transaction. Given that one is for MongoDB and one is for Pinecone, as long as your aware of the risk of the MongoDB or Pinecone transaction failing (which is looks like you are), I don’t really see an issue with it.

The nesting in this case looks like the MongoDB transaction is the top of the hierarchy and the Pinecone transaction is the inner transaction of the MongoDB transaction, meaning if the inner transaction fails, so does the outer transaction, as you’ve described. The practice seems to indicate that if the inner fails, the outer should rollback, which happens as you’ve described.

Further reading I found interesting on this are here and here (not technology specific, mainly for the context on nested transactions).

1 Like

Thank you for your answer and the links! Seems like my approach is fine!