New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transaction API error: Transaction already closed: Transaction is no longer valid. Last state: 'Expired' P2028 #13713
Comments
I get the same error. Any resolve ? |
This error is causing me a lot of trouble, I'm happy to try to get more information. Is there anything I can do to get some more useful data for debugging it? Would really like to get this resolved one way or another. |
I tried add max options is work fine and I changing the value based on NODE_ENV |
Yes this bug keeps troubling and blocks the development. Have tried killing idle processes, disconnecting all open connections, stopping database server but nothing works. Somehow it finds that some transaction was not closed properly. This issue was closed with #9584 in version 3.9 |
Still exists on 4.0.0 |
Any update on this? |
Excessive CPU usage was fixed in prisma/prisma-engines#3028. |
Unfortunately two months back we had to shift to pg (node-postgres) from prisma to get rid of the issue. |
@cesarvspr @felipdc @Abdulrahmanelheyb @revmischa Any help with creating a reproduction of this? We would love to be able to understand this and fix it - but right now we just do not have any code and way to run it that would lead to this error state. Thanks! |
Hi, I'm also experiencing this issue. I will attempt to reproduce it in a simplified environment later on today UPDATE: unable to reproduce today, will continue through the week |
Can you give us some sort of figures to work with? What does a 'bunch' mean? At the moment we cannot reproduce this. |
Hello, Any update on this ? We are experiencing this issue very often too. What is done is a simple interactive transaction. Sometimes it success, sometimes not without the underlying any change on the underlying data. Thanks a lot for any help |
Still Experiencing this issue, |
Solved this, |
And how @bazzscript did you solde this while using a transaction ? Thanks |
@w8ze-devel could you look at increasing the timeout for your transaction. To me it sounds like your transaction is timing out before all your operations have completed. |
@garrensmith When I faced this issue 4 weeks ago, I was using loops of various complexities (which could have been improved overtime). I kept increasing the timeout, but that didn't fix the issue regardless of the timeout. I'm also still unable to reproduce it again |
I had the same issue and I solved it with a Promise.all const documentsToArchive: DocumentAttributes[] = [...]
await prisma.$transaction(async (trx) => {
for (const documentToArchive of documentsToArchive) {
await trx.documents.updateMany({ data: { status: 'ARCHIVED'}, where: documentToArchive })
}
}) Now I do const documentsToDelete: DocumentAttributes[] = [...]
await prisma.$transaction(async (trx) => {
await Promise.all(documentsToArchive.map((documentToArchive) =>
trx.documents.updateMany({ data: { status: 'ARCHIVED'}, where: documentToArchive })))
}) Hope it can help to reproduce & to solve for some people ✌🏻 |
Thank you so much for proceeding! my commented
I have checked that the loop rewritten to |
@Pompedup your example also hints at the transaction actually timing out, since the problem was solved by rewriting a slow sequential algorithm to a faster concurrent one. Not taking the specific of your query into the account and just talking about the fact that you don't have any dependencies between your queries, I think a slightly better option would've been using a batch transaction instead of an interactive transaction: await prisma.$transaction(documentToArchive.map((documentToArchive) =>
prisma.documents.updateMany({ data: { status: 'ARCHIVED'}, where: documentToArchive })) However, regardless of the type of transaction, the big problem here is The best option would be getting rid of both the transaction and the loop altogether and replacing it with a single
I don't think this is correct. An array is not an async iterable and doesn't require |
Hey everyone! This is a complex issue in a sense that people run into it under different circumstances, and whether it is easily reproducible or only occurs intermittently or even once also differs for various people. From what I can see, in most cases where some kind of reproduction was provided, the error looks very plausible and doesn't seem to be an issue in Prisma looking at the code alone without specific numbers. I believe that in those cases where we couldn't see a reproduction, even where the error was very elusive and hard to reproduce again for the reporter, the error was still technically correct and the transactions timed out. However, there is still an open question of whether it is expected for the operations inside the transaction to take as much time as they took for everyone who reported it — as well as what exactly the numbers were. I think some people might just be facing network issues that make their queries take longer than usual to get to the database (the original report, for example, mentions serverless functions, which implies remote database), but there could theoretically be a possibility that we might have a performance issue somewhere which makes some operation slower when used inside a transaction, although I haven't seen an indication of it so far. It also looks like some people were just confused by the error itself and thought it was some internal error and not a user-facing error indicating that the transaction has timed out. To alleviate these problems, we would like to improve the error messages related to interactive transactions to make them more informative and user-friendly, re-add the information that was lost since version 4.1.0, as well as provide new information and more visibility into the expired transactions. Aside from the reason why the transaction was closed, expired transactions will return the transaction timeout and the actual time that has passed since the start of the transaction as a part of the error message: Hopefully this should be less confusing and more helpful for those who are doing a lot of work in the transaction callback and run into this error as expected. For those who don't believe they should be running into this error, it should provide more context about your circumstances that you could share with us — and I would suggest opening new, more specific, issues instead of reusing this very general and ambiguous one. Any reports about this functionality not working as you would expect are still very welcome and wanted! While the new error message will provide some basic visibility into the timing of an interactive transaction (which is already immensely more useful than nothing), I would suggest using tracing for those who want more advanced visibility and to learn why exactly a transaction is taking as much time as it does. We would really appreciate if you include this information in your bug reports btw! |
Just a thought regarding the proposed error message: Would it be good to include a link or a hint how and where to increase the transaction timeout? |
Yes, definitely. |
Make the error messages for closed transactions more detailed, add extra context about the transaction timeout. Before: - `Transaction API error: Transaction already closed: A query/commit/rollback cannot be executed on a closed transaction..` (also note the double "." at the end) Now: - `Transaction API error: Transaction already closed: A query/commit/rollback cannot be executed on a committed transaction.` - `Transaction API error: Transaction already closed: A query/commit/rollback cannot be executed on a transaction that was rolled back.` - `Transaction API error: Transaction already closed: A query/commit/rollback cannot be executed on an expired transaction. The timeout for this transaction was X ms, however Y ms passed since the start of the transaction. Consider increasing the interactive transaction timeout or doing less work in the transaction.` Additionally, the "Transaction not found error" is now also more verbose, ref: https://www.notion.so/disconnect-with-iTX-f3cfee3ff4924e40aa90aadb2454e9fa?d=3bd7c7103b02461bbfe414a978a994c1#547ab127682b41898c87bdd5c841c0bf Also contains minor cleanup things related to iTX: * Remove the unused `CachedTx::Aborted` variant * Remove references to an obsolete env var that doesn't exist since #3028 from comments and `.envrc` Client PR: prisma/prisma#16382 Closes: prisma/prisma#13713 Ref: prisma/prisma#16050 Ref: #3028
We could add a link to the docs there, this is a nice idea. Sorry I didn't see your comment earlier. Optimally we'd also need to add a subheader we could link to directly, as currently the nearest header we could link to is https://www.prisma.io/docs/concepts/components/prisma-client/transactions#interactive-transactions-in-preview, and one would need to scroll a bit until the transaction options. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Ran into this issue today as well – turns out the fix was to convert my |
I recently started to experience this. I confirm @steven-tey 's solutions works |
after reading provided solutions and comments, I didn't understand why it works with good old for loop but not with one feedback, I would expect to see more comments from Prisma team. It will give a bit more relief to people using Prisma on their production environment as database layer libraries are one of the core and fundamental parts of most web/server based applications. |
If you can still reproduce some part of this problem, please open a new issue and provide all the information the bug issue template asks for - and optimally a reproduction we can run ourselves. Thanks. For us the issue was closed by improving the error message, as there was no clear reproduction of what was going on. We unfortunately can not possibly respond to all not directly related comments in all our issues. That would make things a lot more confusing to everyone (and impossible for us to manage). Hope you understand. |
I know it's late, but in case you're using prisma transaction inside an arr.foreach() it works if you not use the transaction refence, I mean this: use this ( watch the prisma inside the loop, maybe tx is not recognised inside the scope) I know we're missing the point of the transaction, but maybe you can use it anyway in an specific part of a bigger transaction. it worked for me. |
Is there any way to increase the timeout? This is a hard blocker for us right now. |
This is from the official document. |
I think most people are encountering this issue through running concurrent interactive transactions in a |
Why does this work? Man I've been breaking my head about this issue, it's also only an issue on a Windows machine, on my mac it's working fine using for...of |
I also found that this error would come up when I had a transaction that called an awaited promise to Prisma that was NOT using the transaction. |
In my case this error appeared because I fired but did not await a promise from inside the async transaction callback |
|
I solved using tthe promise.all as @Eh-haque commented above |
ran into the same issue - if you need to run transactions inside a loop, consider using a generator function. |
For anyone trying add a LOT of data (for example, during seeding, more than 10,000 rows, Prisma will still timeout even with Promise.all) ✅ Works under 500ms to add over 10k rows.. const chunkSize = 100; // I found 100 to work the fastest
const chunks = [];
for (let i = 0; i < seed_data.length; i += chunkSize) {
chunks.push(seed_data.slice(i, i + chunkSize));
}
await Promise.all(
chunks.map(async (chunk) => {
await db.$transaction(async (tx) => {
await Promise.all(
chunk.map((chunkData) => {
return tx.YOUR_TABLE_HERE.create({
data: chunkData,
});
}),
);
});
}),
); |
Bug description
I'm using 3.14.0
I increased timeouts and these queries generally take ~500ms though they can take longer under load
Slack thread: https://prisma.slack.com/archives/CCWDULGUW/p1654457710257189
How to reproduce
Do a bunch of complex interactive transactions in different lambda functions running in parallel
Expected behavior
No response
Prisma information
3.14.0, in a lambda layer
serverless stack
Environment & setup
Prisma Version
The text was updated successfully, but these errors were encountered: