Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go回滚不了,请教下是什么问题? #526

Open
BlackAntSir opened this issue Oct 26, 2024 · 2 comments
Open

go回滚不了,请教下是什么问题? #526

BlackAntSir opened this issue Oct 26, 2024 · 2 comments

Comments

@BlackAntSir
Copy link

BlackAntSir commented Oct 26, 2024

代码如下:
func CreateByDtm(ctx context.Context) (uint64, error) {
userId = generate.userID() //生成自增ID
userData := user.CreateUserInfoRequest{//省略非重要代码}
storeData := store.CreateStoreInfoRequest{ //省略非重要代码 }

// 初始化 DTM 工作流,三个参数分别为: dtm 服务器地址、业务服务器地址、gRPC 服务器
grpcServer := grpc.NewServer()
//workflow.InitGrpc(dtmutil.DefaultGrpcServer, busi.BusiGrpc, grpcServer)
    workflow.InitGrpc("127.0.0.1:36790", "127.0.0.1:9090", grpcServer)

gid := shortuuid.New()
wfName := fmt.Sprintf("%s-grpc-%s", dtmimp.GetFuncName(), gid)
err := workflow.Register(wfName, func(wf *workflow.Workflow, data []byte) error {
	// 创建用户事务分支
	wf.NewBranch().OnRollback(func(bb *dtmcli.BranchBarrier) error {
		fmt.Println("===CreateUserRevert===")
		// 回滚时删除用户
		_, err := rpc.UserClient.CreateUserRevert(wf.Context, &user.IdRequest{
			Id: userId,
		})
		return err
	})

	// 创建用户
	userInfo, err := rpc.UserClient.CreateUser(wf.Context, &userData)
	if err != nil {
		fmt.Println("用户创建失败:", err)
		return err
	}

	// 创建店铺事务分支
	wf.NewBranch().OnRollback(func(bb *dtmcli.BranchBarrier) error {
		fmt.Println("===CreateStoreRevert===", storeId)
		// 回滚时删除店铺
		_, err = rpc.StoreClient.CreateStoreRevert(wf.Context, &store.StoreIdequest{
			Id: storeId,
		})
		return err
	})

	// 创建店铺--故意触发第二个子事务的失败
	storeInfo, err := rpc.StoreClient.CreateStore(wf.Context, &storeData)
	if err != nil {
		fmt.Println("店铺创建失败:", err)
		return err
	}

	return nil
})

// 事务注册失败返回
if err != nil {
	fmt.Println("事务注册失败:", err.Error())
	return 0, errors.New("事务注册失败")
}

// 事务提交-执行工作流
    data, err := proto.Marshal(&user.IdRequest{Id: userId })
_, err = workflow.ExecuteCtx(context.Background(), wfName, gid, data)
if err != nil {
	fmt.Println("出错:" + err.Error())
	// 处理事务提交失败的情况
	return 0, errors.New("处理事务提交失败的情况")
}

return userId, err

}

func main() {
go busi.RunGrpc(grpcServer)
//注册用户
CreateByDtm(context.Background())
}

成功提交至DTM服务,也正确创建了用户。现在遇到的问题是,当创建店铺事务子步骤失败后,代码没有执行预期的回滚逻辑 wf.NewBranch().OnRollback(...)。而且直接又执行创建用户的正常事务逻辑?请问那里出了问题?

@yedf2
Copy link
Contributor

yedf2 commented Nov 16, 2024

当创建店铺事务子步骤失败后,代码没有执行预期的回滚逻辑

你需要按照约定返回失败,其他的失败,DTM不清楚是暂时的失败还是业务真正失败了,所以会不断地尝试

直接又执行创建用户的正常事务逻辑

对于分布式事务来说,需要子业务时幂等的,可以看看dtm相关的文档

dtm-examples下面有许多的例子,参考例子做一下实验。如果你的问题能够通过例子复现,那么就容易解决了

@furucong
Copy link

要想实现回滚,rpc.UserClient.CreateUser()返回的gRPC状态码必须是ABORTED(10)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants