[seata]TCC模式的回滚触发

2024-07-15 937 views
1

JDK 1.8 SEATA: seata-all 1.5.2

使用TCC模式,目前碰到的问题是: 通过@GlobalTransactional开启全局事务后顺序执行两个@TwoPhaseBusinessAction的事务方法A、方法B, 方法A、方法B都已定义各自rollbackMethod, 在测试时发现如果是在方法B的一阶段提交中抛出异常,方法A的rollbackMethod可以被触发调用,而方法B的rollbackMethod则无法被触发。 同样再测试了两种场景,包括方法A、B、C以及只有方法A的场景下,只要是异常抛出的一阶段提交方法都无法触发自己的rollbackMethod,而其他一阶段提交成功的方法都能触发回滚。 请问是否对于seata的机制理解有误,望不吝赐教。

回答

1

我在1.5.2,也遇到了同样的问题,不知道是不是对seata tcc的理解有误。的确如你所说的那样B的rollbackMethod无法触发。

跪求官方解答 @a364176773

5

加一句,xid是有传递到b服务的

正常流程,B的confirm方法能够触发。

8

我跟踪调试了一下源码,发现问题点应该是在TCCResourceManager的branchRollback方法上。

image

因为seata1.5.1追加了防止幂等、悬挂和空回滚的机制,所以我这边也打开了useTCCFence = true的开关。然后发现只要是使用此机制时,因为触发了防悬挂机制,按照官方文档说明:

因此当此一段提交方法没有成功完成,也不会进行回滚操作。

这个感觉和整个机制设计有关系,希望官方答疑解惑一下,谢谢。 @a364176773

8

我是没有开useTCCFence哦

3

你的issue跟这个issue不是一个问题,这个issue极大可能是xid没传递,方法b没有注册分支,所以二阶段没被调用,如果是本地的两个方法,建议issue用户排查注解的切面是否有进,比如同个类中隐式this导致动态代理失效都是有可能的

1

另外tcc没有一阶段提交的说法,只有二阶段提交的说法

7

一阶段没有成功本地事务就不会提交,不会提交为什么需要回滚?

5

嗯,您说的我理解。所以seata的tcc模式还是只针对数据库层面的提交及回滚控制吧。 如果一阶段针对的是对redis这种的操作,实际上也没有办法通过二阶段的rollback方法做redis的操作补偿对吧?@a364176773

1

redis这种你要关掉防悬挂,而且redis哪有资源可以预留,你只不过用tcc来方便操作redis罢了,如果是这样,你把redis的动作直接放在二阶段做不就好了,try里一个空实现

1

好的,理解了,谢谢。