Sharing a Postgres (or other DBMS) transaction context between processes

Viewed 159

A common pattern in monolithic application design is to delegate business logic to a dedicated service, passing in an open transaction as, for example, a javax.persistence.EntityTransaction instance in Java, or an sql.Transaction in Go.

Go example:

// business.go

type BusinessLogicService interface {
    DoSomething(tx *sql.Transaction)
}

type businessLogicService struct {
}

func (s *BusinessLogicService) DoSomething(tx *sql.Transaction) {
    tx.ExecuteContext(.....)
}

func NewBusinessLogicService() {
    return &businessLogicService{}
}

// server.go

ctx := context.Background()
tx, err := db.BeginTx(ctx)
if err != nil {
    log.Fatal(err)
}

bls := business.NewBusinessLogicService()
bls.DoSomething(tx)

tx.Commit()

Could the same effect be achieved in an architecture where each of these components are implemented in a different language/runtime? In such an application, Postgres is responsible for doing the 'bookkeeping' in relation to the DB transaction. It seems to me that it should be possible to pass a similar 'handle' for the transaction to another process to read its state and append operations.

For example the equivalent business logic is provided as a gRPC service with the following definition:

message TransactionInfo {
  string transaction_id = 1;
}

message DoSomethingRequest {
  TransactionInfo transaction_info = 1;
}
  
message DoSomethingResponse {
}

service BusinessLogicService {
  rpc DoSomething(DoSomethingRequest) returns (DoSomethingResponse)
}

The server process BEGINs the transaction and passes a reference to this BusinessLogicService.

ctx := context.Background()
tx, err := db.BeginTx(ctx)
if err != nil {
    log.Fatal(err)
}

conn, err := grpc.Dial(*serverAddr, opts...)
if err != nil {
  ...
}
defer conn.Close()
bls := pb.NewBusinessLogicClient()

/// SOMEHOW PASS THE TX OBJECT TO THE REMOTE SERVICE
txObj := &pb.TransactionInfo{....???????????.....}

result := bls.DoSomething(txObj)

tx.Commit()

Is this possible with Postgres or another DBMS?

0 Answers
Related