Well, you should Pick only GraphQL if you are using GraphQL and you will have these guarantees. For DQL, an Upsert Logic should be fine. We have DQL working like this for years. Just a few people complained about it in 4 years and once they learned how to, they get used to it.
The Upsert logic is
1 - A Block to check the existing data. And use variables to capture that info.
2 - A Block to mutate the data based on the data within the variables.
With Upsert Block you can do any complex logic to avoid duplicates - check the docs for more https://dgraph.io/docs/mutations/upsert-block/#sidebar
PS. You have also to pay attention to the Data Modeling in GraphQL. Which is standardized for GraphQL’s context. Mean, the mutation modeling has its rules. You may find them on docs or here in the community posts. In DQL the data modeling is completely free to model.