Closed nikolasburk closed 2 years ago
MongoDB itself started supporting multi-document transactions starting with 4.0.
The Prisma Mongo connector is not officially tested against 4.0 yet but we would expect it to just work. Making use of the transactional capabilities that 4.0 offers is something we would need to explicitly add though.
We currently do not think that the implementation is the main hurdle, the biggest task is to get an understanding of the performance implications and potential deadlock issues this brings with it.
The SQL connectors also always run with transactionality enabled by default. It is not yet clear to us whether this should be the case for Mongo as well or whether users would like to configure this (to avoid performance penalties for example.)
If any one has a strong opinion on this or has specific use cases where they want / do not want it we would like to hear from you!
Thanks a lot for the explanation!
I think this is a very important product decision because not supporting transactions would mean that we're accepting projects to be inconsistent which will lead to errors further down the road when using the same project.
Consider the example from this issue where the following datamodel was used:
type User {
id: ID! @id
name: String
companies: [Company!]! @relation(link: INLINE)
}
type Company {
id: ID! @id
name: String
user: User!
}
Note that the user
field is required on the Company
model.
But because the transaction failed, there was a Company
node created that had no User
associated with it! This will lead to a GraphQL error when that Company
node with the user
relation is being retrieved.
I just tested with my own API using MongoDB 4.0 and it actually worked. I linked my User with Logs into my type User and Log and then created a new user with the object:
{ firstName: "Allan", lastName: "Lima", email: "allanpinheirodelima@gmail.com", emailVerified: false, logs: { create: [{ resource: "prisma", operation: "delete" }] } }
It was created, but it was a small scale test. Everything worked fine. I don't think we should rush things, but it looks pretty solid with MongoDB 4.0. I'll be watching this thread to know your conclusions
edit
I don't know yet how to format code like the comment from nikolasburk
Hey @allanplima, here's how to format multi-line code on Github. Might I also suggest using json
or js
as the language like so.
```js
<code goes here>
```
Also if your new to markdown in general I recommend reading Github's markdown guide or the Mastering Markdown guide they are both pretty similar so only reading one is fine.
Doesn't work for me with MongoDB 4.0.6.
Im trying this (from the docs)
const newUserWithLinks = await prisma
.createUser({
name: "Alice",
email: "alice@prisma.io",
password: "IlikeTurtles",
links: {
create: [{
description: "My first link",
url: "https://www.prisma.io"
}, {
description: "My second link",
url: "https://www.howtographql.com"
}]
},
})
the model is:
type Link {
id: ID! @id
createdAt: DateTime!
description: String!
url: String!
postedBy: User
votes: [Vote!]! @relation(link: INLINE)
}
type User {
id: ID! @id
name: String!
email: String! @unique
password: String!
links: [Link!]! @relation(link: INLINE)
votes: [Vote!]! @relation(link: INLINE)
}
type Vote {
id: ID! @id
link: Link!
user: User!
}
and I get the following error:
{
"result": {
"data": null,
"errors": [
{
"message": "Variable '$data' expected value of type 'UserCreateInput!' but got: {\"name\":\"Alice\",\"email\":\"alice@prisma.io\",\"password\":\"IlikeTurtles\",\"links\":{\"create\":[{\"description\":\"My first link\",\"url\":\"https://www.prisma.io\"},{\"description\":\"My second link\",\"url\":\"https://www.howtographql.com\"}]}}. Reason: 'links.create[0].createdAt' Expected non-null value, found null. (line 1, column 11):\nmutation ($data: UserCreateInput!) {\n ^",
"locations": [
{
"line": 1,
"column": 11
}
]
},
{
"message": "Variable '$data' expected value of type 'UserCreateInput!' but got: {\"name\":\"Alice\",\"email\":\"alice@prisma.io\",\"password\":\"IlikeTurtles\",\"links\":{\"create\":[{\"description\":\"My first link\",\"url\":\"https://www.prisma.io\"},{\"description\":\"My second link\",\"url\":\"https://www.howtographql.com\"}]}}. Reason: 'links.create[0].createdAt' Expected non-null value, found null. (line 1, column 11):\nmutation ($data: UserCreateInput!) {\n ^",
"locations": [
{
"line": 1,
"column": 11
}
]
}
],
"status": 200
}
}
EDIT:
Didn't pay attention to the reason. I just had to remove the createdAt
field from Link
and now it works!
so Prisma is not safe and I should implement my own API with mongoose
is there any plan for it ...?
Currently, nested mutations with the MongoDB connector are not executed transactionally and therefore might bring your project into an inconsistent state and break the API. See this issue as an example.