diff --git a/packages/client/src/runtime/getPrismaClient.ts b/packages/client/src/runtime/getPrismaClient.ts index 5b71c916fccb..18784bbb479d 100644 --- a/packages/client/src/runtime/getPrismaClient.ts +++ b/packages/client/src/runtime/getPrismaClient.ts @@ -830,9 +830,6 @@ Or read our docs at https://www.prisma.io/docs/concepts/components/prisma-client if (activeScope !== itxContext.scopeId) { throw new Error('Concurrent nested transactions are not supported') } - - // Re-use the underlying transaction in the engine by reusing the same transaction id. - options.newTxId = itxContext.txId } scopeStack.push(scopeId) @@ -842,7 +839,8 @@ Or read our docs at https://www.prisma.io/docs/concepts/components/prisma-client maxWait: options?.maxWait ?? this._engineConfig.transactionOptions.maxWait, timeout: options?.timeout ?? this._engineConfig.transactionOptions.timeout, isolationLevel: options?.isolationLevel ?? this._engineConfig.transactionOptions.isolationLevel, - newTxId: options.newTxId, + // Re-use the underlying transaction in the engine by reusing the same transaction id. + newTxId: isNested ? itxContext.txId : undefined, } let info: Transaction.InteractiveTransactionInfo try { diff --git a/packages/client/tests/functional/interactive-transactions/tests.ts b/packages/client/tests/functional/interactive-transactions/tests.ts index 061d4a7cd3e4..6c1bc7f53ce4 100644 --- a/packages/client/tests/functional/interactive-transactions/tests.ts +++ b/packages/client/tests/functional/interactive-transactions/tests.ts @@ -521,6 +521,29 @@ testMatrix.setupTestSuite( expect(users.map((u) => u.email)).toEqual([outerEmail1, outerEmail2].sort()) }) + testIf(provider !== Providers.MONGODB)('sql: nested transaction does not mutate the options object', async () => { + const email1 = `user_${copycat.uuid(251)}@website.com` + const email2 = `user_${copycat.uuid(252)}@website.com` + const options = { maxWait: 5000, timeout: 5000 } + + await prisma.$transaction(async (tx) => { + await tx.$transaction(async (tx2) => { + await tx2.user.create({ data: { email: email1 } }) + }, options) + }, options) + + expect(options).toStrictEqual({ maxWait: 5000, timeout: 5000 }) + + await prisma.$transaction(async (tx) => { + await tx.user.create({ data: { email: email2 } }) + }, options) + + const users = await prisma.user.findMany({ + where: { email: { in: [email1, email2] } }, + }) + expect(users).toHaveLength(2) + }) + testIf(provider !== Providers.MONGODB)('sql: enforce order for nested transactions', async () => { const result = prisma.$transaction(async (tx) => { const nested = tx.$transaction(async (tx2) => {