在saga模式中,当State中的IsAsync被设置为true时,按照官方文档,该state服务将被异步调用,那么当该异步state服务执行失败时,seata会如何对该异步state服务进行补偿(向后回滚/向前重试)?来保证该saga事务的最终一致性?
[seata]saga模式中State异步执行失败时,如何保证最终一致性?
回答
@long187 龙哥,之前好像是你添加的这个异步化功能,这个是当时的issues #1843 ,龙哥帮忙看下这个问题呗,感谢
@a364176773 老哥,可以帮忙看下这个问题吗?我现在的理解是:saga对state做的异步不需要保证最终数据一致性,因为使用state异步的业务都是一些就算失败也不影响业务的场景,比如发短信和发邮件。因此想要保证最终一致性的重要业务,是不应该使用saga的state异步的。
请问我的理解对吗?
某些场景下不关注执行和结果,可以理解为rpc的oneway调用,此种情况下使用异步,可以提升整个状态机执行效率。
即使执行异常,比如说漏发了短信,在业务上也是可以接受的,所以一般此种业务到底是不是最终一致的范畴是有待商榷的。
另外,不关注异步State的执行结果,并不意味着我们不会对其进行补偿,当异步State后续State执行失败时,我们仍然会触发状态机的补偿动作, 如果既要效率,又要保证一致,我们可以设置异步State的补偿动作,状态机失败的时候在补偿动作里面去做兜底,比如判断有没有发送过,是否重新发送短信。状态机成功的时候在Callback里面做check。
首先非常感谢老哥的解答,看了回复后,我还有个疑问,那就是关于回复中的“当异步State后续State执行失败时,我们仍然会触发状态机的补偿动作”表述。
假如在我这个saga状态机流程中全都是异步State,而这些异步State并没有自己后续的State了,那么回复中的“当异步State后续State执行失败时”时机就不存在了。
那么在这种场景下,这些异步State会并行执行,互不干扰,此时触发状态机补偿的时机是什么? 换种说法的话,就是怎么知道本次saga全局事务执行的结果是成功的还是失败的?
目前我能想到的方案是,在状态机执行成功和状态机执行失败的时候,都要做check来进行兜底补偿,但是这种方案感觉复杂性太高,老哥有好的办法吗?
这种场景我理解使用并行task会更加合适,不过目前并行task还在开发设计中。