Transaction with bad input should rollback (when using middleware)
See original GitHub issueBug description
If one query in the transaction fails the input validation, the transaction doesn’t rollback and the other queries proceed normally.
Error:
Error: Argument city for data.address.create.city is missing.
at Document.validate (/app/node_modules/.prisma/client/runtime/index.js:32462:19)
at NewPrismaClient._executeRequest (/app/node_modules/.prisma/client/runtime/index.js:34399:17)
at NewPrismaClient._requestWithMiddlewares (/app/node_modules/.prisma/client/runtime/index.js:34350:19)
at /app/node_modules/.prisma/client/runtime/index.js:34343:53
at /app/src/common/prisma/retry.js:35:38
at NewPrismaClient._requestWithMiddlewares (/app/node_modules/.prisma/client/runtime/index.js:34343:16)
at /app/node_modules/.prisma/client/runtime/index.js:34332:54
at AsyncResource.runInAsyncScope (async_hooks.js:197:9)
at NewPrismaClient._request (/app/node_modules/.prisma/client/runtime/index.js:34332:27)
at Object.requestTransaction (/app/node_modules/.prisma/client/runtime/index.js:34469:39)
How to reproduce
Consider the following schema:
model User {
id Int @id @default(autoincrement())
name String
}
Run the following code:
const prisma = new PrismaClient();
prisma.$transaction([
prisma.user.create({ data: { name: 'emile' } })
prisma.user.create({ data: {} })
])
There should be a user in the database as the transaction is not rollback.
Expected behavior
The transaction should be rollback.
Environment & setup
- OS: Linux
- Database: PostgreSQL
- Node.js version: 14
- Prisma version: 2.21.2
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:8 (8 by maintainers)
Top Results From Across the Web
Practical Transaction Handling in Microservice Architecture
In the case of failure in a service in the workflow, we need to rollback the overall transaction.
Read more >hotchocolate - Is there a way to implement a transaction-per ...
At the beginning of the request, we begin a transaction and then delegate to the next middleware. If any unhandled exceptions occur, we...
Read more >ASP.NET Core: One transaction per server roundtrip - Medium
One (simple) solution is to wrap it all up into one database transaction, which can be rolled back in case of failure (or...
Read more >A clean way to implement database transaction in Golang
The idea is simple: it takes a context and a callback function as input, then it will start a new db transaction, create...
Read more >Middleware Architecture - Transactions
Concurrent execution allows taking advantage of multiprocessing facilities, both for process execution and for input-output. Concurrent ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
If we “fix” things so that it can fail/stop on
Document.validate
, we’ll end up with a mediocre solution that just stops on the first error. Rollback won’t happen and you’ll have a partial “transaction” applied. Transactions are sequential, before you move to the next one you wait that the middleware has finished (and that’s the query exec). So no rollback like asked in the OP. (this is again becauseasync
makes the failure non-immediate).So in link with what I mentioned above, the current transaction implementation relies on failure immediateness to rollback. For this reason, since middlewares are asynchronous by design and under the hood, we cannot rollback. Doing
await next(params)
triggers the query to be executed. This is a problem because we expect a result, but at the same time we want previous queries to rollback if needed. Because of this, we cannot rely on immediate failure to rollback, we areawait
ing results - one at a time.The obvious solution now is that we implement https://github.com/prisma/prisma/issues/1844