zhenlanghuo

Results 14 comments of zhenlanghuo

dtm-examples 的go mod如下 module github.com/dtm-labs/dtm-examples go 1.15 require ( github.com/dtm-labs/client v1.15.1 github.com/gin-gonic/gin v1.7.7 github.com/go-redis/redis/v8 v8.11.5 github.com/go-resty/resty/v2 v2.7.0 github.com/go-sql-driver/mysql v1.6.0 github.com/lib/pq v1.10.3 github.com/lithammer/shortuuid/v3 v3.0.7 go.mongodb.org/mongo-driver v1.9.1 google.golang.org/grpc v1.47.0 google.golang.org/protobuf v1.28.0 gorm.io/driver/mysql...

> > 4. TccBTransInTry 执行失败 (brand_id 02) > > 5. 然后修改 http_workflow_tcc_barrier 的代码:1) 修改gid为上一次执行的gid;2) 设置 TccBTransInTry 执行成功 > > 作为分布式应用,需要做到幂等,这个是基本要求。4和7的行为不是幂等行为,因此属于你的业务程序设计问题,而不是dtm的行为。如果业务不幂等,无论dtm怎么做,都无法保证数据一致 @yedf2 1. 使用了barrier不应该就是由barrier来保证幂等吗 2. 4和7的行为为什么不是幂等,4的失败可能是网络超时失败,实际执行成功的,所以再次执行,7返回成功,这样不是幂等吗 3. 子事务都回滚了,再次执行子事务的try,返回成功,难道这是正确的吗

> 是的,barrier可以保证幂等,但是你在barrier记录失败之后,又设置TccBTransInTry 执行成功,这就矛盾了,barrier记录失败之后,永远不再会返回成功了 假设 TccBTransInTry 是一个扣金币的动作,TccBTransOutTry 成功了,TccBTransInTry失败了(金币不足),然后TccBTransOutRollback,在submit全局事务之前,程序崩溃了(用debug调试运行,在submit全局事务之前退出)。之后重启程序,dtm服务器那边resume,这个时候会重新调用 TccBTransOutTry , barrier会直接返回成功(不会真正执行TccBTransOutTry),TccBTransInTry 此时也成功(此时金币足够了),之后就会执行 TccBTransOutCommit 和 TccBTransInCommit,相当于 TccBTransIn既执行了rollback也执行了commit 通过以上的方式手动模拟金币不足返回错误的情况 @yedf2

> > TccBTransInTry失败了(金币不足) > > 这个事情发生了之后,返回ResultFailure,就不会再返回成功了,即使金币足够了,也只会返回barrier保存的失败 @yedf2 不啊,返回ResultFailure之后,barrier不会保存失败,是rollback的

> 这样吧,你给个复现了问题的可运行的代码例子,而不是你手动的debug改数据,这样描述的问题最清晰最准确,就能够弄清楚怎么回事了 @yedf2 我在dtm-examples上写了一下可以复现问题的代码例子,但是没有权限push分支(从main分支拉出来的分支),无法跟你这边交流

> > > 是的,barrier可以保证幂等,但是你在barrier记录失败之后,又设置TccBTransInTry 执行成功,这就矛盾了,barrier记录失败之后,永远不再会返回成功了 > > > > > > 假设 TccBTransInTry 是一个扣金币的动作,TccBTransOutTry 成功了,TccBTransInTry失败了(金币不足),然后TccBTransOutRollback,在submit全局事务之前,程序崩溃了(用debug调试运行,在submit全局事务之前退出)。之后重启程序,dtm服务器那边resume,这个时候会重新调用 TccBTransOutTry , barrier会直接返回成功(不会真正执行TccBTransOutTry),TccBTransInTry 此时也成功(此时金币足够了),之后就会执行 TccBTransOutCommit 和 TccBTransInCommit,相当于 TccBTransIn既执行了rollback也执行了commit > > > > 通过以上的方式手动模拟金币不足返回错误的情况 > >...

> > > > TccBTransOutRollback 在崩溃前,执行成功了没有?如果成功了,dtm恢复以后是直接走rollback流程,而不是像你说的,重新从try再走一遍流程 TccBTransOutRollback执行成功之后,业务服务器崩溃,全局事务未到终态,dtm服务器会不断得调用resume来重试,业务服务器恢复之后,resume在业务服务器中执行的顺序是从头开始(用之前的全局事务id),调用TccBTransOutTry,此时虽然该全局事务下该事务分支已经有了rollback的记录,但是barrier是返回的成功,所以接下来会继续执行TccBTransInTry,如果这个时候TccBTransInTry执行成功,就会进入到commit的流程 @relxet

> 而且try是客户端触发的,try再执行一次,就是一个新的事务 resume的话,不是新的事务,是之前的全局事务 @relxet

> 你搞错了,try是ap端直接call的,tm不会去call try,何来从头开始。ap重新call try,就要注册一个新的gid,就是一个新事物了。 @relxet 你有尝试过resume吗,resume是带着原来的全局事务gid,重新跑的 我说的重新跑,是指在ap端重新跑

> 你一个事务分支的rollback都执行过了,还要让ap从try再跑一遍?你这流程就不是dtm的流程。你就要让dtm把当前这个事务rollback完,ap端重新发起一次新的事务,而不是原来的事务重新从try跑一遍。 @relxet 这个是workflow这个模式的执行机制啊,不是我定的啊,你有看懂workflow的执行机制吗