81 lines
2.0 KiB
Go
81 lines
2.0 KiB
Go
package dtmcli
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/yedf/dtm/common"
|
|
)
|
|
|
|
type BusiFunc func(db *sql.DB) (interface{}, error)
|
|
|
|
type TransInfo struct {
|
|
TransType string
|
|
Gid string
|
|
BranchID string
|
|
BranchType string
|
|
}
|
|
|
|
func (t *TransInfo) String() string {
|
|
return fmt.Sprintf("transInfo: %s %s %s %s", t.TransType, t.Gid, t.BranchID, t.BranchType)
|
|
}
|
|
|
|
func TransInfoFromReq(c *gin.Context) *TransInfo {
|
|
return &TransInfo{
|
|
TransType: c.Query("trans_type"),
|
|
Gid: c.Query("gid"),
|
|
BranchID: c.Query("branch_id"),
|
|
BranchType: c.Query("branch_type"),
|
|
}
|
|
}
|
|
|
|
type BarrierModel struct {
|
|
common.ModelBase
|
|
TransInfo
|
|
}
|
|
|
|
func (BarrierModel) TableName() string { return "dtm_barrier.barrier" }
|
|
|
|
func insertBarrier(tx *sql.Tx, transType string, gid string, branchID string, branchType string) (int64, error) {
|
|
if branchType == "" {
|
|
return 0, nil
|
|
}
|
|
res, err := tx.Exec("insert into dtm_barrier.barrier(trans_type, gid, branch_id, branch_type) values(?,?,?,?)", transType, gid, branchID, branchType)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return res.RowsAffected()
|
|
}
|
|
|
|
func ThroughBarrierCall(db *sql.DB, transInfo *TransInfo, busiCall BusiFunc) (res interface{}, rerr error) {
|
|
tx, rerr := db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
if rerr != nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
if x := recover(); x != nil {
|
|
tx.Rollback()
|
|
panic(x)
|
|
} else if rerr != nil {
|
|
tx.Rollback()
|
|
} else {
|
|
tx.Commit()
|
|
}
|
|
}()
|
|
|
|
originType := map[string]string{
|
|
"cancel": "action",
|
|
"compensate": "action",
|
|
}[transInfo.BranchType]
|
|
originAffected, _ := insertBarrier(tx, transInfo.TransType, transInfo.Gid, transInfo.BranchID, originType)
|
|
currentAffected, rerr := insertBarrier(tx, transInfo.TransType, transInfo.Gid, transInfo.BranchID, transInfo.TransType)
|
|
if currentAffected == 0 || (originType == "cancel" || originType == "compensate") && originAffected > 0 {
|
|
res = "SUCCESS" // 如果被忽略,那么直接返回 "SUCCESS",表示成功,可以进行下一步
|
|
return
|
|
}
|
|
res, rerr = busiCall(db)
|
|
return
|
|
}
|