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

时间:2021-04-11 16:17:47

标签: database postgresql architecture transactions

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

Go 示例:

// 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 是否可行?

0 个答案:

没有答案
相关问题