diff --git a/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/schema.prisma b/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/schema.prisma index f2983997d55a..31c3d89449ee 100644 --- a/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/schema.prisma +++ b/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/schema.prisma @@ -15,6 +15,7 @@ model User { // / name comment name String? posts Post[] + val Int? } model Post { diff --git a/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/test.ts b/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/test.ts index 2bab71621e58..9817664874a3 100644 --- a/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/test.ts +++ b/packages/client/src/__tests__/integration/happy/interactive-transactions-postgres/test.ts @@ -575,6 +575,67 @@ describe('interactive transactions', () => { expect(users.length).toBe(0) }) + + /** + * Makes sure that the engine can process when the transaction has locks inside + * Engine PR - https://github.com/prisma/prisma-engines/pull/2811 + * Issue - https://github.com/prisma/prisma/issues/11750 + */ + test('high concurrency with SET FOR UPDATE', async () => { + jest.setTimeout(60_000) + const CONCURRENCY = 12 + + await prisma.user.create({ + data: { + email: 'x', + name: 'y', + val: 1, + }, + }) + + const promises = [...Array(CONCURRENCY)].map(() => + prisma.$transaction( + async (transactionPrisma) => { + await transactionPrisma.$queryRaw`SELECT id from "User" where email = 'x' FOR UPDATE` + + const user = await transactionPrisma.user.findUnique({ + rejectOnNotFound: true, + where: { + email: 'x', + }, + }) + + // Add a delay here to force the transaction to be open for longer + // this will increase the chance of deadlock in the itx transactions + // if deadlock is a possiblity. + await new Promise((r) => setTimeout(r, 100)) + + const updatedUser = await transactionPrisma.user.update({ + where: { + email: 'x', + }, + data: { + val: user.val + 1, + }, + }) + + return updatedUser + }, + { timeout: 60000, maxWait: 60000 }, + ), + ) + + await Promise.allSettled(promises) + + const finalUser = await prisma.user.findUnique({ + rejectOnNotFound: true, + where: { + email: 'x', + }, + }) + + expect(finalUser.val).toEqual(13) + }) }) beforeAll(async () => { diff --git a/packages/client/src/__tests__/integration/happy/interactive-transactions-sqlite/dev.db b/packages/client/src/__tests__/integration/happy/interactive-transactions-sqlite/dev.db index 389f9f4c371f..28600fd21fbc 100644 Binary files a/packages/client/src/__tests__/integration/happy/interactive-transactions-sqlite/dev.db and b/packages/client/src/__tests__/integration/happy/interactive-transactions-sqlite/dev.db differ