91 lines
3.1 KiB
Go
91 lines
3.1 KiB
Go
package examples
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/yedf/dtm/dtmcli"
|
|
"github.com/yedf/dtm/dtmgrpc"
|
|
"google.golang.org/protobuf/types/known/emptypb"
|
|
)
|
|
|
|
func init() {
|
|
addSample("grpc_saga_barrier", func() string {
|
|
req := dtmcli.MustMarshal(&TransReq{Amount: 30})
|
|
gid := dtmgrpc.MustGenGid(DtmGrpcServer)
|
|
saga := dtmgrpc.NewSaga(DtmGrpcServer, gid).
|
|
Add(BusiGrpc+"/examples.Busi/TransOutBSaga", BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req).
|
|
Add(BusiGrpc+"/examples.Busi/TransInBSaga", BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req)
|
|
err := saga.Submit()
|
|
dtmcli.FatalIfError(err)
|
|
return saga.Gid
|
|
})
|
|
}
|
|
|
|
func sagaGrpcBarrierAdjustBalance(sdb *sql.Tx, uid int, amount int) (interface{}, error) {
|
|
_, err := dtmcli.StxExec(sdb, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid)
|
|
return dtmcli.ResultSuccess, err
|
|
|
|
}
|
|
|
|
func (s *busiServer) TransInBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*emptypb.Empty, error) {
|
|
req := TransReq{}
|
|
dtmcli.MustUnmarshal(in.BusiData, &req)
|
|
return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), req.TransInResult, dtmcli.GetFuncName())
|
|
}
|
|
|
|
func (s *busiServer) TransOutBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*emptypb.Empty, error) {
|
|
req := TransReq{}
|
|
dtmcli.MustUnmarshal(in.BusiData, &req)
|
|
return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutResult.Fetch(), req.TransOutResult, dtmcli.GetFuncName())
|
|
}
|
|
|
|
func (s *busiServer) TransInRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*emptypb.Empty, error) {
|
|
req := TransReq{}
|
|
dtmcli.MustUnmarshal(in.BusiData, &req)
|
|
return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransInRevertResult.Fetch(), "", dtmcli.GetFuncName())
|
|
}
|
|
|
|
func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*emptypb.Empty, error) {
|
|
req := TransReq{}
|
|
dtmcli.MustUnmarshal(in.BusiData, &req)
|
|
return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutRevertResult.Fetch(), "", dtmcli.GetFuncName())
|
|
}
|
|
|
|
func sagaBarrierTransIn(c *gin.Context) (interface{}, error) {
|
|
req := reqFrom(c)
|
|
if req.TransInResult != "" {
|
|
return req.TransInResult, nil
|
|
}
|
|
barrier := MustBarrierFromGin(c)
|
|
return barrier.Call(sdbGet(), func(sdb *sql.Tx) (interface{}, error) {
|
|
return sagaBarrierAdjustBalance(sdb, 1, req.Amount)
|
|
})
|
|
}
|
|
|
|
func sagaBarrierTransInCompensate(c *gin.Context) (interface{}, error) {
|
|
barrier := MustBarrierFromGin(c)
|
|
return barrier.Call(sdbGet(), func(sdb *sql.Tx) (interface{}, error) {
|
|
return sagaBarrierAdjustBalance(sdb, 1, -reqFrom(c).Amount)
|
|
})
|
|
}
|
|
|
|
func sagaBarrierTransOut(c *gin.Context) (interface{}, error) {
|
|
req := reqFrom(c)
|
|
if req.TransInResult != "" {
|
|
return req.TransInResult, nil
|
|
}
|
|
barrier := MustBarrierFromGin(c)
|
|
return barrier.Call(sdbGet(), func(sdb *sql.Tx) (interface{}, error) {
|
|
return sagaBarrierAdjustBalance(sdb, 2, -req.Amount)
|
|
})
|
|
}
|
|
|
|
func sagaBarrierTransOutCompensate(c *gin.Context) (interface{}, error) {
|
|
barrier := MustBarrierFromGin(c)
|
|
return barrier.Call(sdbGet(), func(sdb *sql.Tx) (interface{}, error) {
|
|
return sagaBarrierAdjustBalance(sdb, 2, reqFrom(c).Amount)
|
|
})
|
|
}
|