Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

The MongoDB connector should support transactions for nested mutations #3738

Closed
nikolasburk opened this issue Dec 19, 2018 · 7 comments
Closed

Comments

@nikolasburk
Copy link
Member

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.

@do4gr
Copy link
Member

do4gr commented Jan 3, 2019

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!

@nikolasburk
Copy link
Member Author

nikolasburk commented Jan 4, 2019

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.

@allanplima
Copy link

allanplima commented Jan 22, 2019

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

@johnsonjo4531
Copy link

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.

@monojack
Copy link

monojack commented Mar 9, 2019

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!

@byteab
Copy link

byteab commented Jul 1, 2019

so Prisma is not safe and I should implement my own API with mongoose

@akhilshastri
Copy link

is there any plan for it ...?

@janpio janpio closed this as completed Sep 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants