-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Calling the "main" prisma client within an interactive transaction can lead to errors at high concurrency #12277
Description
Bug description
If I have the following transaction and run 8 in parallel it all works fine, but if I run 9 in parallel then the requests start failing with Transaction API error: Transaction already closed: Transaction is no longer valid. Last state: 'Expired'.:
const client = new PrismaClient();
await client.$transaction(async (t) => {
// 👀 Note were using the client directly, not the transaction client here
// If we use the transaction client here we have no issue
await client.user.findMany();
await t.user.findMany();
});It looks like the call to the client.user... starts to take longer than the transaction timeout causing the failure.
In our use case we happened to have a transaction with some queries to fetch data and some to update data. We were using the transaction client for all the update queries, but accidentally used the "main" client for one of the fetches; I guess we were working on the assumption that we didn't need the fetch to fail atomically in the same way as the updates.
Either way once we tracked this down the fix was trivial, just update the offending query to use the transaction client. I'm just raising this issue for visibility!
How to reproduce
Minimal reproduction here:
https://github.com/henrymunro/prisma-transaction-repro
Expected behavior
I'm not sure really, I guess for it to work if I query with the "main" client? Or maybe to throw a more meaningful error if that is not supported.
Prisma information
Using 3.10.0, but see the repro for full details.
Environment & setup
- OS: Mac OS
- Database: Postgres
- Node.js version: v14.15.3
Prisma Version
6.14.9