dtm-labs / dtm

A distributed transaction framework, supports workflow, saga, tcc, xa, 2-phase message, outbox patterns, supports many languages.
http://d.dtm.pub
BSD 3-Clause "New" or "Revised" License
10.18k stars 979 forks source link

tcc事务,分支代码不执行 #523

Open zzispp opened 2 months ago

zzispp commented 2 months ago

只会执行try,confrim和cancel不执行,`func (uc OrderUsecase) CreateOrder(ctx context.Context, o model.Order) (*model.Order, error) { // 判断是否支持该链 supported, err := uc.grpcClient.Block.IsSupportedChainNetwork(ctx, &blockV1.IsSupportedChainNetworkRequest{ Chain: o.Chain, Network: o.Network, }) if err != nil { return nil, err } if !supported.Supported { return nil, errors.InternalServer("CHAIN_NOT_SUPPORTED", "不支持的链网络") }

// 获取币种
tokens, err := uc.grpcClient.Block.GetTokens(ctx, &blockV1.GetTokensRequest{
    Chain:   o.Chain,
    Network: o.Network,
})
if err != nil {
    return nil, err
}

var tokenAddress string
for _, token := range tokens.Tokens {
    if strings.EqualFold(token.Symbol, o.Symbol) {
        tokenAddress = token.Address
        o.Symbol = token.Symbol
        break
    }
}

if len(tokenAddress) == 0 {
    return nil, errors.InternalServer("TOKEN_NOT_FOUND", "未找到代币")
}

// 设置订单信息
o.TokenAddress = tokenAddress

// 检查订单是否存在
order, err := uc.repo.FindByOrderID(ctx, o.OrderID, o.MerchantID)
if err != nil {
    return nil, err
}

if order.ID > 0 {
    return nil, errors.InternalServer("ORDER_EXISTS", "订单已存在")
}

// 尝试从数据库中获取已收款的或可用的地址
address, err := uc.grpcClient.Block.FindActiveOrNewAddress(ctx, &blockV1.FindActiveOrNewAddressRequest{
    Chain:   o.Chain,
    Network: o.Network,
})
if err != nil {
    return nil, err
}

// 设置订单信息
o.Address = address.Address
o.CreatedTimeStamp = time.Now().Unix()
o.ExpiredTimeStamp = o.CreatedTimeStamp + 3600

// 使用DTM创建TCC事务
dtmServer := "discovery:///dtmservice"
busiServer := "discovery:///block-service"
gid := dtmgrpc.MustGenGid(dtmServer)
uc.log.Infof("gid: %s", gid)
err = dtmgrpc.TccGlobalTransaction(dtmServer, gid, func(tcc *dtmgrpc.TccGrpc) error {
    // 更新地址状态
    var tryReply blockV1.TryUpdateAddressStatusReply
    if err := tcc.CallBranch(
        &blockV1.TryUpdateAddressStatusRequest{
            Chain:   o.Chain,
            Network: o.Network,
            Address: address.Address,
            Status:  blockV1.AddressStatus_ADDRESS_STATUS_IN_USE,
        },
        busiServer+"/api.block.v1.Block/TryUpdateAddressStatus",
        busiServer+"/api.block.v1.Block/ConfirmUpdateAddressStatus",
        busiServer+"/api.block.v1.Block/CancelUpdateAddressStatus",
        &tryReply,
    ); err != nil {
        return err
    }

    // 保存订单到数据库
    _, err = uc.repo.Save(ctx, o)
    err = errors.InternalServer("ORDER_SAVE_FAILED", "订单保存失败")
    if err != nil {
        return err
    }

    return nil
})
if err != nil {
    uc.log.Errorf("TCC事务执行错误: %v", err)
    return nil, err
}
uc.log.Info("TCC 事务成功提交")
return o, nil

}`

yedf2 commented 2 months ago

您好,您可以通过dtm-examples项目,修改其中的例子,复现你的问题,然后把详情发到这个issue里。 只是看你的片段代码,我也无法准确诊断出您的问题