关于微服务化后多个接口间如何事务回滚的疑惑

发布于 2022-09-06 03:10:38 字数 422 浏览 23 评论 0

这年头个个都在说微服务,我理解是,如果一个系统所有大模块都微服务化后,那么所有业务,都需要调用对应的微服务接口来处理。

那么如果一个业务,涉及到要同时调用N个微服务的接口时,如果接口出问题后,虽然这个接口内部可以回滚,但是之前调用的接口,没有被通知到需要回滚,这时候不就坑大了?

我目前想到的解决方案是,所有微服务接口必须提供额外一个回滚用的特定接口,供调用者在遇到其他接口出错后,主动调用。

但是这样一来,不就反而增加了工作量?


自己补一下找到的解决方案:
http://www.cnblogs.com/wxd010...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦一生花开无言 2022-09-13 03:10:38

这是一个好问题。
我之前也有过和你一样的疑问。
不谈2PC和CAP。
给题主的问题总结一下。
微服务面临的一致性问题?

服务拆分之后,各个服务之间会有自己数据库,传统的数据库ACID我们已经不能再使用。

如何解决一致性问题:
事件驱动实现最终一致性

理论上的话和图也不多说了,网上太多。
show u the code.

翻译题主的问题成为代码:

public function DoSomeThing()
{
    if (this->serviceA->doSomeThing()) {
        throw RpcException('A服务异常');
    } else {
        print 'A服务执行成功 \r\n';
    }
    if (this->serviceB->doSomeThing()) {
        throw RpcException('B服务异常');
    } else {
        print 'B服务执行成功 \r\n';
    }
    if (this->serviceC->doSomeThing()) {
        throw RpcException('C服务异常');
    } else {
        print 'C服务执行成功 \r\n';
    }        
    // A服务执行成功
    // B服务执行成功
    // C服务执行失败
}

解决方案:

public function DoSomeThing()
{
    if (this->serviceA->doSomeThing()) {
        throw RpcException('A服务异常');
    } else {
        print 'A服务执行成功 \r\n';
    }
    this->mq->send(bParams));
    this->mq->send(cParams));
}

在MQ消费失败的时候,可以通知上游业务回滚数据,但是我们一般不建议这样做。
因为涉及到上游业务比较多的时候,一层层回滚数流程太复杂了。

需要通过MQ的ACK机制,在业务层保证一定成功即可。

举例一个典型的业务场景: 下单和扣减库存(普通情况,非抢购场景)。

用户下单成功,发送MQ通知给库存服务,库存服务扣减库存。
如果第一次消费的时候,库存服务的DB由于某种原因挂了或者其它情况导致库存没有扣减成功,
此时应当标记这个MQ消息消费失败,消息回重新放回队列,等待下次消费,如果每次都不成功,
说明程序有BUG(反思一下测试严谨性?)。
解决这个bug,再消费(MQ没有ACK就会一直存在),这也是我们说的最终一致性。

// 因为你在业务上,也不可能去取消用户的订单。
人事已非 2022-09-13 03:10:38

思路和上面的相同,就是实现的时候觉得太复杂了

ABC 三个服务,顺序调用A->B->C ,假如C失败了
需要定义的方法是
A
Do(){}
UnDo(){}
B
Do(){}
UnDo(){}
C
Do(){}
UnDo(){}

所有的服务都要写一遍撤销操作的代码

然后 比如 C失败了,将失败的消息放到消息队列中通知AB,然后AB消费消息后执行UnDo(),这个UnDo必须是幂等性的,不影响多次回滚操作

这样来处理应该是可以满足需求的,主要的痛点就是太麻烦了,所有的操作都需要自己来实现回滚

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文