在进程之间共享Postgres(或其他DBMS)事务上下文

单体应用程序设计中的一个常见模式是将业务逻辑委托给专用服务,将开放事务作为例如javax.persistence.EntityTransactionJava 中的实例或sql.TransactionGo 中的实例传递。

去例子:

// 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()

在这些组件中的每一个都以不同的语言/运行时实现的架构中,是否可以实现相同的效果?在这样的应用程序中,Postgres 负责执行与数据库事务相关的“簿记”。在我看来,应该可以将事务的类似“句柄”传递给另一个进程以读取其状态和附加操作。

例如,等效的业务逻辑作为具有以下定义的 gRPC 服务提供:

message TransactionInfo {
  string transaction_id = 1;
}

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

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

服务器处理BEGIN事务并传递对此 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()

Postgres 或其他 DBMS 可以做到这一点吗?

以上是在进程之间共享Postgres(或其他DBMS)事务上下文的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>