mirror of https://github.com/dtm-labs/dtm.git
10 changed files with 327 additions and 65 deletions
@ -0,0 +1,90 @@ |
|||||
|
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) |
||||
|
}) |
||||
|
} |
||||
@ -1,24 +0,0 @@ |
|||||
package examples |
|
||||
|
|
||||
import ( |
|
||||
"github.com/yedf/dtm/dtmcli" |
|
||||
) |
|
||||
|
|
||||
func init() { |
|
||||
addSample("saga_wait", func() string { |
|
||||
dtmcli.Logf("a saga busi transaction begin") |
|
||||
req := &TransReq{ |
|
||||
Amount: 30, |
|
||||
TransInResult: "SUCCESS", |
|
||||
TransOutResult: "SUCCESS", |
|
||||
} |
|
||||
saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). |
|
||||
Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). |
|
||||
Add(Busi+"/TransIn", Busi+"/TransInRevert", req) |
|
||||
saga.WaitResult = true // 设置为等待结果模式,后面的submit调用,会等待服务器处理这个事务。如果Submit正常返回,那么整个全局事务已成功完成
|
|
||||
err := saga.Submit() |
|
||||
dtmcli.Logf("result gid is: %s", saga.Gid) |
|
||||
dtmcli.FatalIfError(err) |
|
||||
return saga.Gid |
|
||||
}) |
|
||||
} |
|
||||
Loading…
Reference in new issue