|
|
|
@ -28,26 +28,24 @@ func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (ret in |
|
|
|
"trans_type": "tcc", |
|
|
|
} |
|
|
|
tcc := &Tcc{Dtm: dtm, Gid: gid} |
|
|
|
resp, err := common.RestyClient.R().SetBody(data).Post(tcc.Dtm + "/prepare") |
|
|
|
if IsFailure(resp, err) { |
|
|
|
resp, err := CallDtm(dtm, data, "prepare", &TransOptions{}) |
|
|
|
if err != nil { |
|
|
|
return resp, err |
|
|
|
} |
|
|
|
// 小概率情况下,prepare成功了,但是由于网络状况导致上面Failure,那么不执行下面defer的内容,等待超时后再回滚标记事务失败,也没有问题
|
|
|
|
defer func() { |
|
|
|
var x interface{} |
|
|
|
if x = recover(); x != nil || IsFailure(ret, rerr) { |
|
|
|
resp, err = common.RestyClient.R().SetBody(data).Post(dtm + "/abort") |
|
|
|
} else { |
|
|
|
resp, err = common.RestyClient.R().SetBody(data).Post(dtm + "/submit") |
|
|
|
} |
|
|
|
if IsFailure(resp, err) { |
|
|
|
common.RedLogf("submitting or abort global transaction error: %v resp: %s", err, resp.String()) |
|
|
|
x := recover() |
|
|
|
operation := common.If(x == nil && rerr == nil, "submit", "abort").(string) |
|
|
|
resp, err = CallDtm(dtm, data, operation, &TransOptions{}) |
|
|
|
if rerr == nil { |
|
|
|
rerr = err |
|
|
|
} |
|
|
|
if x != nil { |
|
|
|
panic(x) |
|
|
|
} |
|
|
|
}() |
|
|
|
ret, rerr = tccFunc(tcc) |
|
|
|
rerr = CheckResult(ret, rerr) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
@ -68,22 +66,20 @@ func TccFromReq(c *gin.Context) (*Tcc, error) { |
|
|
|
// 函数首先注册子事务的所有分支,成功后调用try分支,返回try分支的调用结果
|
|
|
|
func (t *Tcc) CallBranch(body interface{}, tryURL string, confirmURL string, cancelURL string) (*resty.Response, error) { |
|
|
|
branchID := t.NewBranchID() |
|
|
|
resp, err := common.RestyClient.R(). |
|
|
|
SetBody(&M{ |
|
|
|
"gid": t.Gid, |
|
|
|
"branch_id": branchID, |
|
|
|
"trans_type": "tcc", |
|
|
|
"status": "prepared", |
|
|
|
"data": string(common.MustMarshal(body)), |
|
|
|
"try": tryURL, |
|
|
|
"confirm": confirmURL, |
|
|
|
"cancel": cancelURL, |
|
|
|
}). |
|
|
|
Post(t.Dtm + "/registerTccBranch") |
|
|
|
if IsFailure(resp, err) { |
|
|
|
return resp, err |
|
|
|
_, err := CallDtm(t.Dtm, &M{ |
|
|
|
"gid": t.Gid, |
|
|
|
"branch_id": branchID, |
|
|
|
"trans_type": "tcc", |
|
|
|
"status": "prepared", |
|
|
|
"data": string(common.MustMarshal(body)), |
|
|
|
"try": tryURL, |
|
|
|
"confirm": confirmURL, |
|
|
|
"cancel": cancelURL, |
|
|
|
}, "registerTccBranch", &TransOptions{}) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
return common.RestyClient.R(). |
|
|
|
resp, err := common.RestyClient.R(). |
|
|
|
SetBody(body). |
|
|
|
SetQueryParams(common.MS{ |
|
|
|
"dtm": t.Dtm, |
|
|
|
@ -93,4 +89,5 @@ func (t *Tcc) CallBranch(body interface{}, tryURL string, confirmURL string, can |
|
|
|
"branch_type": "try", |
|
|
|
}). |
|
|
|
Post(tryURL) |
|
|
|
return resp, CheckResponse(resp, err) |
|
|
|
} |
|
|
|
|