fix barrier return
This commit is contained in:
parent
e73e20a867
commit
b9ef5c8005
@ -46,6 +46,16 @@ type BarrierModel struct {
|
|||||||
TransInfo
|
TransInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logExec(tx *sql.Tx, query string, args ...interface{}) (sql.Result, error) {
|
||||||
|
logrus.Printf("executing: "+query, args...)
|
||||||
|
return tx.Exec(query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func logQueryRow(tx *sql.Tx, query string, args ...interface{}) *sql.Row {
|
||||||
|
logrus.Printf("querying: "+query, args...)
|
||||||
|
return tx.QueryRow(query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// TableName gorm table name
|
// TableName gorm table name
|
||||||
func (BarrierModel) TableName() string { return "dtm_barrier.barrier" }
|
func (BarrierModel) TableName() string { return "dtm_barrier.barrier" }
|
||||||
|
|
||||||
@ -53,14 +63,14 @@ func insertBarrier(tx *sql.Tx, transType string, gid string, branchID string, br
|
|||||||
if branchType == "" {
|
if branchType == "" {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
res, err := tx.Exec("insert into dtm_barrier.barrier(trans_type, gid, branch_id, branch_type, reason) values(?,?,?,?,?)", transType, gid, branchID, branchType, reason)
|
res, err := logExec(tx, "insert into dtm_barrier.barrier(trans_type, gid, branch_id, branch_type, reason) values(?,?,?,?,?)", transType, gid, branchID, branchType, reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return res.RowsAffected()
|
return res.RowsAffected()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThroughBarrierCall2 子事务屏障,详细介绍见 https://zhuanlan.zhihu.com/p/388444465
|
// ThroughBarrierCall 子事务屏障,详细介绍见 https://zhuanlan.zhihu.com/p/388444465
|
||||||
// db: 本地数据库
|
// db: 本地数据库
|
||||||
// transInfo: 事务信息
|
// transInfo: 事务信息
|
||||||
// bisiCall: 业务函数,仅在必要时被调用
|
// bisiCall: 业务函数,仅在必要时被调用
|
||||||
@ -94,10 +104,11 @@ func ThroughBarrierCall(db *sql.DB, transInfo *TransInfo, busiCall BusiFunc) (re
|
|||||||
currentAffected, rerr := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, ti.BranchType, ti.BranchType)
|
currentAffected, rerr := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, ti.BranchType, ti.BranchType)
|
||||||
logrus.Printf("originAffected: %d currentAffected: %d", originAffected, currentAffected)
|
logrus.Printf("originAffected: %d currentAffected: %d", originAffected, currentAffected)
|
||||||
if (ti.BranchType == "cancel" || ti.BranchType == "compensate") && originAffected > 0 { // 这个是空补偿,返回成功
|
if (ti.BranchType == "cancel" || ti.BranchType == "compensate") && originAffected > 0 { // 这个是空补偿,返回成功
|
||||||
return common.MS{"dtm_result": "SUCCESS"}, nil
|
res = common.MS{"dtm_result": "SUCCESS"}
|
||||||
|
return
|
||||||
} else if currentAffected == 0 { // 插入不成功
|
} else if currentAffected == 0 { // 插入不成功
|
||||||
var result string
|
var result sql.NullString
|
||||||
err := tx.QueryRow("select result from dtm_barrier.barrier where trans_type=? and gid=? and branch_id=? and branch_type=? and reason=?",
|
err := logQueryRow(tx, "select result from dtm_barrier.barrier where trans_type=? and gid=? and branch_id=? and branch_type=? and reason=?",
|
||||||
ti.TransType, ti.Gid, ti.BranchID, ti.BranchType, ti.BranchType).Scan(&result)
|
ti.TransType, ti.Gid, ti.BranchID, ti.BranchType, ti.BranchType).Scan(&result)
|
||||||
if err == sql.ErrNoRows { // 这个是悬挂操作,返回失败,AP收到这个返回,会尽快回滚
|
if err == sql.ErrNoRows { // 这个是悬挂操作,返回失败,AP收到这个返回,会尽快回滚
|
||||||
res = common.MS{"dtm_result": "FAILURE"}
|
res = common.MS{"dtm_result": "FAILURE"}
|
||||||
@ -107,14 +118,18 @@ func ThroughBarrierCall(db *sql.DB, transInfo *TransInfo, busiCall BusiFunc) (re
|
|||||||
rerr = err
|
rerr = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 返回上一次的结果
|
if result.Valid { // 数据库里有上一次结果,返回上一次的结果
|
||||||
rerr = json.Unmarshal([]byte(result), &res)
|
res = json.Unmarshal([]byte(result.String), &res)
|
||||||
return
|
return
|
||||||
|
} else { // 数据库里没有上次的结果,属于重复空补偿,直接返回成功
|
||||||
|
res = common.MS{"dtm_result": "SUCCESS"}
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res, rerr = busiCall(db)
|
res, rerr = busiCall(db)
|
||||||
if rerr == nil { // 正确返回了,需要将结果保存到数据库
|
if rerr == nil { // 正确返回了,需要将结果保存到数据库
|
||||||
sval := common.MustMarshalString(res)
|
sval := common.MustMarshalString(res)
|
||||||
_, rerr = tx.Exec("update dtm_barrier.barrier set result=? where trans_type=? and gid=? and branch_id=? and branch_type=?", sval,
|
_, rerr = logExec(tx, "update dtm_barrier.barrier set result=? where trans_type=? and gid=? and branch_id=? and branch_type=?", sval,
|
||||||
ti.TransType, ti.Gid, ti.BranchID, ti.BranchType)
|
ti.TransType, ti.Gid, ti.BranchID, ti.BranchType)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@ -36,8 +36,9 @@ func lockOneTrans(expireIn time.Duration) *TransGlobal {
|
|||||||
owner := GenGid()
|
owner := GenGid()
|
||||||
db := dbGet()
|
db := dbGet()
|
||||||
// 这里next_cron_time需要限定范围,否则数据量累计之后,会导致查询变慢
|
// 这里next_cron_time需要限定范围,否则数据量累计之后,会导致查询变慢
|
||||||
|
// 限定update_time < now - 3,否则会出现刚被这个应用取出,又被另一个取出
|
||||||
dbr := db.Must().Model(&trans).
|
dbr := db.Must().Model(&trans).
|
||||||
Where("next_cron_time < date_add(now(), interval ? second) and next_cron_time > date_add(now(), interval -3600 second) and status in ('prepared', 'aborting', 'submitted')", int(expireIn/time.Second)).
|
Where("next_cron_time < date_add(now(), interval ? second) and next_cron_time > date_add(now(), interval -3600 second) and update_time < date_add(now(), interval ? second) and status in ('prepared', 'aborting', 'submitted')", int(expireIn/time.Second), -3+int(expireIn/time.Second)).
|
||||||
Limit(1).Update("owner", owner)
|
Limit(1).Update("owner", owner)
|
||||||
if dbr.RowsAffected == 0 {
|
if dbr.RowsAffected == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -366,7 +366,7 @@ func tccBarrierDisorder(t *testing.T) {
|
|||||||
return res, err
|
return res, err
|
||||||
}))
|
}))
|
||||||
// 注册子事务
|
// 注册子事务
|
||||||
_, err := common.RestyClient.R().
|
r, err := common.RestyClient.R().
|
||||||
SetBody(&M{
|
SetBody(&M{
|
||||||
"gid": tcc.Gid,
|
"gid": tcc.Gid,
|
||||||
"branch_id": branchID,
|
"branch_id": branchID,
|
||||||
@ -379,6 +379,7 @@ func tccBarrierDisorder(t *testing.T) {
|
|||||||
}).
|
}).
|
||||||
Post(tcc.Dtm + "/registerTccBranch")
|
Post(tcc.Dtm + "/registerTccBranch")
|
||||||
e2p(err)
|
e2p(err)
|
||||||
|
assert.True(t, strings.Contains(r.String(), "SUCCESS"))
|
||||||
go func() {
|
go func() {
|
||||||
logrus.Printf("sleeping to wait for tcc try timeout")
|
logrus.Printf("sleeping to wait for tcc try timeout")
|
||||||
<-timeoutChan
|
<-timeoutChan
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user