作者回复: 在二阶段回滚的时候,后镜像是用来做数据校验的:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理。 这里有一个参考例子: https://www.cnblogs.com/dalianpai/p/11864659.html
作者回复: Seata的源码其实并不复杂,如果碰到你说的那种情况,建议要想办法在测试环境重现问题,然后调试跟踪进去才能定位问题根因。
作者回复: 在Seata AT模式下,如果扣款150的事务也是一个Seata全局事务(假设称为事务B),并且分布式事务(假设称为事务A)最终决策回滚,那么A/B之间有写隔离,最终A/B都会回滚,具体原理和流程请参考Seata 官方文档中的案例,写隔离部分: https://seata.io/zh-cn/docs/overview/what-is-seata.html 如果如果扣款150的事务不是一个Seata全局事务,那么需要显示添加@GlobalLock标注,将该事务纳入Seata事务管理,这样也具有写隔离性,参考seata全局锁: https://www.cnblogs.com/lay2017/p/12528071.html
作者回复: 你这个属于一种特例情况,数据量比较大,目前我也没有找到针对你这种情况的优化方案。 因为seata是开源的,代码也不复杂,你这个问题应该跟RM的具体数据库操作方式有关,建议,先通读seata RM的源码。然后,要优化性能,先要测量获得性能数据,看看到底慢在哪里。但是目前seata metrics只有TC支持,RM还不支持,所以你需要自己手动对RM进行埋点,可以考虑prometheus metrcis埋点,或者CAT调用链埋点,找出性能瓶颈在什么地方,然后再考虑优化,必要的时候可能需要自己定制优化一下seata RM的源码。
作者回复: seata AT模式下,如果rollback失败,应该是不可重试的。 会导致TM中的TransactionTemplate#execute抛出回滚异常。可以配置对应回滚的FailureHandler,其中可以发邮件通知进行人工介入,可参考spring下的GlobalTransactionalInterceptor.java代码。 在seata XA模式下,对于某些回滚错误,是会自动重试的,直到事务超时为止,参考rm-datasource下的ResourceManagerXA.java。
作者回复: 可以尝试Cadence分布式工作流方案,解耦更彻底,流程状态更清晰。
作者回复: 看后面的视频,有例子解释。