clear failure
This commit is contained in:
parent
a94761d7f6
commit
b20d18ecbb
@ -59,6 +59,6 @@ func (s *Msg) Submit() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SubmitExt 高级submit,更多的选项和更详细的返回值
|
// SubmitExt 高级submit,更多的选项和更详细的返回值
|
||||||
func (s *Msg) SubmitExt(opt *TransOptions) (TransStatus, error) {
|
func (s *Msg) SubmitExt(opt *TransOptions) error {
|
||||||
return CallDtm(s.Server, &s.MsgData, "submit", opt)
|
return CallDtm(s.Server, &s.MsgData, "submit", opt)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,11 +50,10 @@ func (s *Saga) Add(action string, compensate string, postData interface{}) *Saga
|
|||||||
|
|
||||||
// Submit submit the saga trans
|
// Submit submit the saga trans
|
||||||
func (s *Saga) Submit() error {
|
func (s *Saga) Submit() error {
|
||||||
_, err := s.SubmitExt(&TransOptions{})
|
return s.SubmitExt(&TransOptions{})
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubmitExt 高级submit,更多的选项和更详细的返回值
|
// SubmitExt 高级submit,更多的选项和更详细的返回值
|
||||||
func (s *Saga) SubmitExt(opt *TransOptions) (TransStatus, error) {
|
func (s *Saga) SubmitExt(opt *TransOptions) error {
|
||||||
return CallDtm(s.Server, &s.SagaData, "submit", opt)
|
return CallDtm(s.Server, &s.SagaData, "submit", opt)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,22 +22,22 @@ type TccGlobalFunc func(tcc *Tcc) (*resty.Response, error)
|
|||||||
// dtm dtm服务器地址
|
// dtm dtm服务器地址
|
||||||
// gid 全局事务id
|
// gid 全局事务id
|
||||||
// tccFunc tcc事务函数,里面会定义全局事务的分支
|
// tccFunc tcc事务函数,里面会定义全局事务的分支
|
||||||
func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (status TransStatus, rerr error) {
|
func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) {
|
||||||
data := &M{
|
data := &M{
|
||||||
"gid": gid,
|
"gid": gid,
|
||||||
"trans_type": "tcc",
|
"trans_type": "tcc",
|
||||||
}
|
}
|
||||||
tcc := &Tcc{Dtm: dtm, Gid: gid}
|
tcc := &Tcc{Dtm: dtm, Gid: gid}
|
||||||
status, rerr = CallDtm(dtm, data, "prepare", &TransOptions{})
|
rerr = CallDtm(dtm, data, "prepare", &TransOptions{})
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return status, rerr
|
return rerr
|
||||||
}
|
}
|
||||||
// 小概率情况下,prepare成功了,但是由于网络状况导致上面Failure,那么不执行下面defer的内容,等待超时后再回滚标记事务失败,也没有问题
|
// 小概率情况下,prepare成功了,但是由于网络状况导致上面Failure,那么不执行下面defer的内容,等待超时后再回滚标记事务失败,也没有问题
|
||||||
defer func() {
|
defer func() {
|
||||||
x := recover()
|
x := recover()
|
||||||
var err error
|
var err error
|
||||||
operation := common.If(x == nil && rerr == nil, "submit", "abort").(string)
|
operation := common.If(x == nil && rerr == nil, "submit", "abort").(string)
|
||||||
status, err = CallDtm(dtm, data, operation, &TransOptions{})
|
err = CallDtm(dtm, data, operation, &TransOptions{})
|
||||||
if rerr == nil {
|
if rerr == nil {
|
||||||
rerr = err
|
rerr = err
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ func TccFromReq(c *gin.Context) (*Tcc, error) {
|
|||||||
// 函数首先注册子事务的所有分支,成功后调用try分支,返回try分支的调用结果
|
// 函数首先注册子事务的所有分支,成功后调用try分支,返回try分支的调用结果
|
||||||
func (t *Tcc) CallBranch(body interface{}, tryURL string, confirmURL string, cancelURL string) (*resty.Response, error) {
|
func (t *Tcc) CallBranch(body interface{}, tryURL string, confirmURL string, cancelURL string) (*resty.Response, error) {
|
||||||
branchID := t.NewBranchID()
|
branchID := t.NewBranchID()
|
||||||
_, err := CallDtm(t.Dtm, &M{
|
err := CallDtm(t.Dtm, &M{
|
||||||
"gid": t.Gid,
|
"gid": t.Gid,
|
||||||
"branch_id": branchID,
|
"branch_id": branchID,
|
||||||
"trans_type": "tcc",
|
"trans_type": "tcc",
|
||||||
|
|||||||
@ -19,21 +19,6 @@ func MustGenGid(server string) string {
|
|||||||
return res["gid"]
|
return res["gid"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsFailure 如果err非空,或者ret是http的响应且包含FAILURE,那么返回true。此时认为业务调用失败
|
|
||||||
func IsFailure(res interface{}, err error) bool {
|
|
||||||
resp, ok := res.(*resty.Response)
|
|
||||||
return err != nil || // 包含错误
|
|
||||||
ok && (resp.IsError() || strings.Contains(resp.String(), "FAILURE")) || // resp包含failure
|
|
||||||
!ok && res != nil && strings.Contains(common.MustMarshalString(res), "FAILURE") // 结果中包含failure
|
|
||||||
}
|
|
||||||
|
|
||||||
// PanicIfFailure 如果err非空,或者ret是http的响应且包含FAILURE,那么Panic。此时认为业务调用失败
|
|
||||||
func PanicIfFailure(res interface{}, err error) {
|
|
||||||
if IsFailure(res, err) {
|
|
||||||
panic(fmt.Errorf("dtm failure ret: %v err %v", res, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckResponse 检查Response,返回错误
|
// CheckResponse 检查Response,返回错误
|
||||||
func CheckResponse(resp *resty.Response, err error) error {
|
func CheckResponse(resp *resty.Response, err error) error {
|
||||||
if err == nil && resp != nil {
|
if err == nil && resp != nil {
|
||||||
@ -58,17 +43,6 @@ func CheckResult(res interface{}, err error) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckDtmResponse check the response of dtm, if not ok ,generate error
|
|
||||||
func CheckDtmResponse(resp *resty.Response, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !strings.Contains(resp.String(), "SUCCESS") || resp.IsError() {
|
|
||||||
return fmt.Errorf("dtm response failed: %s", resp.String())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IDGenerator used to generate a branch id
|
// IDGenerator used to generate a branch id
|
||||||
type IDGenerator struct {
|
type IDGenerator struct {
|
||||||
parentID string
|
parentID string
|
||||||
@ -87,28 +61,6 @@ func (g *IDGenerator) NewBranchID() string {
|
|||||||
return g.parentID + fmt.Sprintf("%02d", g.branchID)
|
return g.parentID + fmt.Sprintf("%02d", g.branchID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransStatus 全局事务状态,采用string
|
|
||||||
type TransStatus string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// TransEmpty 空值
|
|
||||||
TransEmpty TransStatus = ""
|
|
||||||
// TransSubmitted 已提交给DTM
|
|
||||||
TransSubmitted TransStatus = "submitted"
|
|
||||||
// TransAborting 正在回滚中,有两种情况会出现,一是用户侧发起abort请求,而是发起submit同步请求,但是dtm进行回滚中出现错误
|
|
||||||
TransAborting TransStatus = "aborting"
|
|
||||||
// TransSucceed 事务已完成
|
|
||||||
TransSucceed TransStatus = "succeed"
|
|
||||||
// TransFailed 事务已回滚
|
|
||||||
TransFailed TransStatus = "failed"
|
|
||||||
// TransErrorPrepare prepare调用报错
|
|
||||||
TransErrorPrepare TransStatus = "error_parepare"
|
|
||||||
// TransErrorSubmit submit调用报错
|
|
||||||
TransErrorSubmit TransStatus = "error_submit"
|
|
||||||
// TransErrorAbort abort调用报错
|
|
||||||
TransErrorAbort TransStatus = "error_abort"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TransOptions 提交/终止事务的选项
|
// TransOptions 提交/终止事务的选项
|
||||||
type TransOptions struct {
|
type TransOptions struct {
|
||||||
// WaitResult 是否等待全局事务的最终结果
|
// WaitResult 是否等待全局事务的最终结果
|
||||||
@ -118,28 +70,26 @@ type TransOptions struct {
|
|||||||
// TransResult dtm 返回的结果
|
// TransResult dtm 返回的结果
|
||||||
type TransResult struct {
|
type TransResult struct {
|
||||||
DtmResult string `json:"dtm_result"`
|
DtmResult string `json:"dtm_result"`
|
||||||
Status TransStatus
|
|
||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallDtm(dtm string, body interface{}, operation string, opt *TransOptions) (TransStatus, error) {
|
// CallDtm 调用dtm服务器,返回事务的状态
|
||||||
|
func CallDtm(dtm string, body interface{}, operation string, opt *TransOptions) error {
|
||||||
resp, err := common.RestyClient.R().SetQueryParams(common.MS{
|
resp, err := common.RestyClient.R().SetQueryParams(common.MS{
|
||||||
"wait_result": common.If(opt.WaitResult, "1", "").(string),
|
"wait_result": common.If(opt.WaitResult, "1", "").(string),
|
||||||
}).SetResult(&TransResult{}).SetBody(body).Post(fmt.Sprintf("%s/%s", dtm, operation))
|
}).SetResult(&TransResult{}).SetBody(body).Post(fmt.Sprintf("%s/%s", dtm, operation))
|
||||||
errStatus := TransStatus("error_" + operation)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errStatus, err
|
return err
|
||||||
}
|
}
|
||||||
tr := resp.Result().(*TransResult)
|
tr := resp.Result().(*TransResult)
|
||||||
if tr.DtmResult == "FAILURE" {
|
if tr.DtmResult == "FAILURE" {
|
||||||
return errStatus, errors.New(tr.Message)
|
return errors.New("FAILURE: " + tr.Message)
|
||||||
}
|
}
|
||||||
return tr.Status, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callDtmSimple(dtm string, body interface{}, operation string) error {
|
func callDtmSimple(dtm string, body interface{}, operation string) error {
|
||||||
_, err := CallDtm(dtm, body, operation, &TransOptions{})
|
return CallDtm(dtm, body, operation, &TransOptions{})
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrFailure 表示返回失败,要求回滚
|
// ErrFailure 表示返回失败,要求回滚
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package dtmcli
|
package dtmcli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -22,8 +21,4 @@ func TestTypes(t *testing.T) {
|
|||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
_, err = TransInfoFromQuery(url.Values{})
|
_, err = TransInfoFromQuery(url.Values{})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
err2 := fmt.Errorf("an error")
|
|
||||||
err3 := CheckDtmResponse(nil, err2)
|
|
||||||
assert.Error(t, err2, err3)
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
dtmcli/xa.go
12
dtmcli/xa.go
@ -99,18 +99,18 @@ func (xc *XaClient) XaLocalTransaction(c *gin.Context, xaFunc XaLocalFunc) (ret
|
|||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, rerr = CallDtm(xc.Server, &M{"gid": xa.Gid, "branch_id": branchID, "trans_type": "xa", "status": "prepared", "url": xc.CallbackURL}, "registerXaBranch", &TransOptions{})
|
rerr = CallDtm(xc.Server, &M{"gid": xa.Gid, "branch_id": branchID, "trans_type": "xa", "status": "prepared", "url": xc.CallbackURL}, "registerXaBranch", &TransOptions{})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// XaGlobalTransaction start a xa global transaction
|
// XaGlobalTransaction start a xa global transaction
|
||||||
func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (status TransStatus, rerr error) {
|
func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (rerr error) {
|
||||||
xa := Xa{IDGenerator: IDGenerator{}, Gid: gid}
|
xa := Xa{IDGenerator: IDGenerator{}, Gid: gid}
|
||||||
data := &M{
|
data := &M{
|
||||||
"gid": gid,
|
"gid": gid,
|
||||||
"trans_type": "xa",
|
"trans_type": "xa",
|
||||||
}
|
}
|
||||||
status, rerr = CallDtm(xc.Server, data, "prepare", &TransOptions{})
|
rerr = CallDtm(xc.Server, data, "prepare", &TransOptions{})
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -118,9 +118,8 @@ func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (status
|
|||||||
// 小概率情况下,prepare成功了,但是由于网络状况导致上面Failure,那么不执行下面defer的内容,等待超时后再回滚标记事务失败,也没有问题
|
// 小概率情况下,prepare成功了,但是由于网络状况导致上面Failure,那么不执行下面defer的内容,等待超时后再回滚标记事务失败,也没有问题
|
||||||
defer func() {
|
defer func() {
|
||||||
x := recover()
|
x := recover()
|
||||||
operation := common.If(x != nil || IsFailure(resp, rerr), "abort", "submit").(string)
|
operation := common.If(x != nil || rerr != nil, "abort", "submit").(string)
|
||||||
var err error
|
err := CallDtm(xc.Server, data, operation, &TransOptions{})
|
||||||
status, err = CallDtm(xc.Server, data, operation, &TransOptions{})
|
|
||||||
if rerr == nil { // 如果用户函数没有返回错误,那么返回dtm的
|
if rerr == nil { // 如果用户函数没有返回错误,那么返回dtm的
|
||||||
rerr = err
|
rerr = err
|
||||||
}
|
}
|
||||||
@ -129,6 +128,7 @@ func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (status
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
resp, rerr = xaFunc(&xa)
|
resp, rerr = xaFunc(&xa)
|
||||||
|
rerr = CheckResponse(resp, rerr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,19 +24,19 @@ func TestTccBarrier(t *testing.T) {
|
|||||||
|
|
||||||
func tccBarrierRollback(t *testing.T) {
|
func tccBarrierRollback(t *testing.T) {
|
||||||
gid := "tccBarrierRollback"
|
gid := "tccBarrierRollback"
|
||||||
resp, err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
resp, err := tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel")
|
_, err := tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel")
|
||||||
assert.True(t, !dtmcli.IsFailure(resp, err))
|
assert.Nil(t, err)
|
||||||
return tcc.CallBranch(&examples.TransReq{Amount: 30, TransInResult: "FAILURE"}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel")
|
return tcc.CallBranch(&examples.TransReq{Amount: 30, TransInResult: "FAILURE"}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel")
|
||||||
})
|
})
|
||||||
assert.True(t, dtmcli.IsFailure(resp, err))
|
assert.Error(t, err)
|
||||||
WaitTransProcessed(gid)
|
WaitTransProcessed(gid)
|
||||||
assert.Equal(t, "failed", getTransStatus(gid))
|
assert.Equal(t, "failed", getTransStatus(gid))
|
||||||
}
|
}
|
||||||
|
|
||||||
func tccBarrierNormal(t *testing.T) {
|
func tccBarrierNormal(t *testing.T) {
|
||||||
gid := "tccBarrierNormal"
|
gid := "tccBarrierNormal"
|
||||||
_, err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
_, err := tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel")
|
_, err := tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
return tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel")
|
return tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel")
|
||||||
@ -50,7 +50,7 @@ func tccBarrierDisorder(t *testing.T) {
|
|||||||
timeoutChan := make(chan string, 2)
|
timeoutChan := make(chan string, 2)
|
||||||
finishedChan := make(chan string, 2)
|
finishedChan := make(chan string, 2)
|
||||||
gid := "tccBarrierDisorder"
|
gid := "tccBarrierDisorder"
|
||||||
_, err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
body := &examples.TransReq{Amount: 30}
|
body := &examples.TransReq{Amount: 30}
|
||||||
tryURL := Busi + "/TccBTransOutTry"
|
tryURL := Busi + "/TccBTransOutTry"
|
||||||
confirmURL := Busi + "/TccBTransOutConfirm"
|
confirmURL := Busi + "/TccBTransOutConfirm"
|
||||||
@ -69,7 +69,7 @@ func tccBarrierDisorder(t *testing.T) {
|
|||||||
return res, err
|
return res, err
|
||||||
}))
|
}))
|
||||||
// 注册子事务
|
// 注册子事务
|
||||||
_, err := dtmcli.CallDtm(tcc.Dtm, M{
|
err := dtmcli.CallDtm(tcc.Dtm, M{
|
||||||
"gid": tcc.Gid,
|
"gid": tcc.Gid,
|
||||||
"branch_id": branchID,
|
"branch_id": branchID,
|
||||||
"trans_type": "tcc",
|
"trans_type": "tcc",
|
||||||
|
|||||||
@ -19,7 +19,7 @@ func TestTcc(t *testing.T) {
|
|||||||
func tccNormal(t *testing.T) {
|
func tccNormal(t *testing.T) {
|
||||||
data := &examples.TransReq{Amount: 30}
|
data := &examples.TransReq{Amount: 30}
|
||||||
gid := "tccNormal"
|
gid := "tccNormal"
|
||||||
_, err := dtmcli.TccGlobalTransaction(examples.DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(examples.DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
_, err := tcc.CallBranch(data, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
_, err := tcc.CallBranch(data, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
return tcc.CallBranch(data, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert")
|
return tcc.CallBranch(data, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert")
|
||||||
@ -30,7 +30,7 @@ func tccNormal(t *testing.T) {
|
|||||||
func tccRollback(t *testing.T) {
|
func tccRollback(t *testing.T) {
|
||||||
gid := "tccRollback"
|
gid := "tccRollback"
|
||||||
data := &examples.TransReq{Amount: 30, TransInResult: "FAILURE"}
|
data := &examples.TransReq{Amount: 30, TransInResult: "FAILURE"}
|
||||||
_, err := dtmcli.TccGlobalTransaction(examples.DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(examples.DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
_, rerr := tcc.CallBranch(data, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
_, rerr := tcc.CallBranch(data, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
||||||
assert.Nil(t, rerr)
|
assert.Nil(t, rerr)
|
||||||
examples.MainSwitch.TransOutRevertResult.SetOnce("PENDING")
|
examples.MainSwitch.TransOutRevertResult.SetOnce("PENDING")
|
||||||
|
|||||||
@ -21,7 +21,7 @@ func TestXa(t *testing.T) {
|
|||||||
|
|
||||||
func xaLocalError(t *testing.T) {
|
func xaLocalError(t *testing.T) {
|
||||||
xc := examples.XaClient
|
xc := examples.XaClient
|
||||||
_, err := xc.XaGlobalTransaction("xaLocalError", func(xa *dtmcli.Xa) (*resty.Response, error) {
|
err := xc.XaGlobalTransaction("xaLocalError", func(xa *dtmcli.Xa) (*resty.Response, error) {
|
||||||
return nil, fmt.Errorf("an error")
|
return nil, fmt.Errorf("an error")
|
||||||
})
|
})
|
||||||
assert.Error(t, err, fmt.Errorf("an error"))
|
assert.Error(t, err, fmt.Errorf("an error"))
|
||||||
@ -30,7 +30,7 @@ func xaLocalError(t *testing.T) {
|
|||||||
func xaNormal(t *testing.T) {
|
func xaNormal(t *testing.T) {
|
||||||
xc := examples.XaClient
|
xc := examples.XaClient
|
||||||
gid := "xaNormal"
|
gid := "xaNormal"
|
||||||
_, err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) {
|
err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) {
|
||||||
req := examples.GenTransReq(30, false, false)
|
req := examples.GenTransReq(30, false, false)
|
||||||
resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa")
|
resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,7 +46,7 @@ func xaNormal(t *testing.T) {
|
|||||||
func xaRollback(t *testing.T) {
|
func xaRollback(t *testing.T) {
|
||||||
xc := examples.XaClient
|
xc := examples.XaClient
|
||||||
gid := "xaRollback"
|
gid := "xaRollback"
|
||||||
_, err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) {
|
err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) {
|
||||||
req := &examples.TransReq{Amount: 30, TransInResult: "FAILURE"}
|
req := &examples.TransReq{Amount: 30, TransInResult: "FAILURE"}
|
||||||
resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa")
|
resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -21,14 +21,14 @@ func TccSetup(app *gin.Engine) {
|
|||||||
// TccFireRequestNested 1
|
// TccFireRequestNested 1
|
||||||
func TccFireRequestNested() string {
|
func TccFireRequestNested() string {
|
||||||
gid := dtmcli.MustGenGid(DtmServer)
|
gid := dtmcli.MustGenGid(DtmServer)
|
||||||
ret, err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
||||||
if dtmcli.IsFailure(resp, err) {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInTccParent", Busi+"/TransInConfirm", Busi+"/TransInRevert")
|
return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInTccParent", Busi+"/TransInConfirm", Busi+"/TransInRevert")
|
||||||
})
|
})
|
||||||
dtmcli.PanicIfFailure(ret, err)
|
e2p(err)
|
||||||
return gid
|
return gid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,13 +36,13 @@ func TccFireRequestNested() string {
|
|||||||
func TccFireRequest() string {
|
func TccFireRequest() string {
|
||||||
logrus.Printf("tcc simple transaction begin")
|
logrus.Printf("tcc simple transaction begin")
|
||||||
gid := dtmcli.MustGenGid(DtmServer)
|
gid := dtmcli.MustGenGid(DtmServer)
|
||||||
ret, err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert")
|
||||||
if dtmcli.IsFailure(resp, err) {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert")
|
return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert")
|
||||||
})
|
})
|
||||||
dtmcli.PanicIfFailure(ret, err)
|
e2p(err)
|
||||||
return gid
|
return gid
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,14 +15,14 @@ import (
|
|||||||
func TccBarrierFireRequest() string {
|
func TccBarrierFireRequest() string {
|
||||||
logrus.Printf("tcc transaction begin")
|
logrus.Printf("tcc transaction begin")
|
||||||
gid := dtmcli.MustGenGid(DtmServer)
|
gid := dtmcli.MustGenGid(DtmServer)
|
||||||
ret, err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) {
|
||||||
resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel")
|
resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel")
|
||||||
if dtmcli.IsFailure(resp, err) {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel")
|
return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel")
|
||||||
})
|
})
|
||||||
dtmcli.PanicIfFailure(ret, err)
|
e2p(err)
|
||||||
return gid
|
return gid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ func XaSetup(app *gin.Engine) {
|
|||||||
// XaFireRequest 注册全局XA事务,调用XA的分支
|
// XaFireRequest 注册全局XA事务,调用XA的分支
|
||||||
func XaFireRequest() string {
|
func XaFireRequest() string {
|
||||||
gid := dtmcli.MustGenGid(DtmServer)
|
gid := dtmcli.MustGenGid(DtmServer)
|
||||||
_, err := XaClient.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) {
|
err := XaClient.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) {
|
||||||
resp, err := xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOutXa")
|
resp, err := xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOutXa")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user