在进程之间共享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 可以做到这一点吗?