Share transaction between multiple distinct services

What I want to do

We are trying to see if it’s possible to create a new transaction using the grpc js library, and then extract some identifier in order to pass it around multiple distinct services/modules in order to have a single atomic multi-service DQL transaction.
We’re hoping that with something like that we can avoid the mess of having to consistently keep track of which services were involved in the (essentially meta-) transaction and rolling them all back individually when it fails, and rather just have everything under one umbrella.

Please list the things you have tried.

So far, we’ve had a look at TxnContext and Txn, and we think it might be possible to generate a new TxnContext at runtime by hand, then set the ctx field inside Txn to the new TxnContext (while vehemently telling typescript to ignore the private setting on the field), but for lack of better documentation, we don’t know whether that will actually work like we want it to, or whether there is a “cleaner”/“more correct” way to do it.

Dgraph metadata

dgraph version

Dgraph version : v21.03.1
Dgraph codename : rocket-1
Dgraph SHA-256 : a00b73d583a720aa787171e43b4cb4dbbf75b38e522f66c9943ab2f0263007fe
Commit SHA-1 : ea1cb5f35
Commit timestamp : 2021-06-17 20:38:11 +0530
Branch : HEAD
Go version : go1.16.2
jemalloc enabled : true

Not sure what you mean. There was a previous transaction?

All Clients have some method to extract UIDs.

This looks very abstract to me. What do you mean?

Are you already using Dgraph? Feels like you have some “Microservices model” running and want to migrate to Dgraph. Am I right?

I guess we can’t help much there.


Sorry, it seems like I wasn’t very clear :sweat_smile:, I have problems putting my thought processes down into words at times, so I’ll just try to rephrase it.

To quickly answer one of your questions first though:

Are you already using Dgraph? Feels like you have some “Microservices model” running and want to migrate to Dgraph. Am I right?

We have a microservice model planned out and are hoping to use Dgraph as part of it, so neither is running yet, so it’s not migration.
However, our aim is to essentially have Dgraph be able to perform distributed transactions as part of sagas, without having to rely on an extra state-tracking layer which would then have to roll back multiple transactions on failure instead of just discarding one.
The reasoning is that, while we could have one service modify parts of another service’s domain since everything is in one database, it entirely defeats the point of separation of concerns and is therefore not acceptable in our workflow. As such we need sagas for requests that require action from multiple services.

In terms of clarifying my previous post, I guess the best way to represent what we want to do would be this process:

Presume there are 3 networked microservices (1 gateway, 2 other services that perform some actions)

  1. Start a transaction in the gateway
  2. Retrieve whatever value uniquely identifies the transaction (I presume it’s the TxnContext?)
  3. Gateway sends said identifier to service 1 which performs whatever queries and mutations are needed in the given transaction, but doesn’t commit
  4. Gateway gets reply from service 1 detailing actions taken
  5. Gateway sends the same identifier to service 2, repeating the same process as service 1
  6. Finally commit the transaction in the gateway and check for success
  7. If success, return to user, else discard the transaction and try again from step 1

The problem we’re having is working out if/how this would be doable.
Our main idea so far as been changing the ctx variable in a Txn object in each service to the TxnContext that we’d create in the gateway as mentioned above. However the field is marked as private, so modifying it would be against spec, and the lack of low-level documentation (at least we have yet to find any) has made it hard to understand whether that idea will actually achieve what we want to do.

I hope that that’s clearer, and sorry for the confusion I may have caused.