P
Prisma4mo ago
Arnór

Transaction API error: Transaction already closed

I'm getting this error in production, but not locally. This is in code that's been running in prod now for about 1-2 years. Full error message:
Transaction API error: Transaction already closed: A commit cannot be executed on an expired transaction. The timeout for this transaction was 5000 ms, however 5408 ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction.
The thing is that I'm getting this error in like 2 seconds from initiating the transaction. I also have a message about the transaction starting 23 seconds ago.. which makes no sense. This started happening about 1 week ago. Environment info: - fastify app on node - prisma 6.9.0 - postgresql 15. The code in question looks like this (i've replaced the table names and fields with fakes, but the code is the same otherwise)
const createResult = await prisma.$transaction(async (tx) => {
const personEntry = await tx.person.create({
data: {
...personData
},
})

for (const hobby of personHobbies) {
await tx.person_hobby.create({
data: {
hobby_play_times: {
createMany: {
data: (hobby.playTime ?? []).map((playTime) => ({
...playTime
})),
},
},
},
})
}

return personEntry
})
const createResult = await prisma.$transaction(async (tx) => {
const personEntry = await tx.person.create({
data: {
...personData
},
})

for (const hobby of personHobbies) {
await tx.person_hobby.create({
data: {
hobby_play_times: {
createMany: {
data: (hobby.playTime ?? []).map((playTime) => ({
...playTime
})),
},
},
},
})
}

return personEntry
})
I haven't had any issues with other transactions - I'm beginning to suspect that this has something to do with the fact that I'm calling createMany inside of a transaction - and perhaps createMany closes the transaction after its first call. Though I cannot find any notes/docs regarding multiple createMany inside of a single transaction It's only showing up now, probably because I have a lot more data now, and each insert is taking a little bit longer than it used to.
5 Replies
Prisma AI Help
Prisma AI Help4mo ago
You selected the carefully hand-crafted route. A dev artisan will respond soon. Meanwhile, the #ask-ai channel awaits if you're curious!
Arnór
ArnórOP4mo ago
FYI the reason i'm using a transaction and the second create statement is done in a loop and not inside the first create call, is because I was having an issue with the ordering of items
Nurul
Nurul4mo ago
Do you get the same error if you increase the timeout from 5 seconds to 10 seconds? https://www.prisma.io/docs/orm/prisma-client/queries/transactions#transaction-options Can you also try using Promise.all instead of for..of loop and check if you still get the error? https://github.com/prisma/prisma/issues/13713#issuecomment-2372688525
Transactions and batch queries (Reference) | Prisma Documentation
This page explains the transactions API of Prisma Client.
GitHub
Transaction API error: Transaction already closed: Transaction is n...
Bug description "Transaction API error: Transaction already closed: Transaction is no longer valid. Last state: 'Expired'." I'm using 3.14.0 I increased timeouts and these que...
Arnór
ArnórOP4mo ago
I've seen the Promise.all suggestions, but those do not make sense for my use case - because I'm specifically doing them in sequence to maintain the autogenerated id order.. and I suspect the Promise.all approach will lead to similar results as createMany - hence why i'm using this approach. Also, these issues that popped up in search results where people claimed to have fixed their issues with a promise.all don't really even address why that results in their issues getting resolved - which I presume is that the overall time it takes ends up being less, since all the queries are sent in one go.. I suppose I should just change the timeout I realized one thing.. it might be that the round-time to my db has increased after both the db and the app changed regions.. I may just be an idiot after all (I mean, I already was one) but I may have just proved it yet again Thanks for the help and sorry for the loss of your time
Nurul
Nurul4mo ago
No worries at all 🙂

Did you find this page helpful?