开发者社区 > 云原生 > 中间件 > 正文

Seata中AT模式下,A服务调用B服务接口,B服务抛出了异常,有没有知道是怎么回事?

Seata中AT模式下,A服务调用B服务接口,B服务抛出了异常,A服务没有感知到。A服务是多数据源(dynamic.seata=true加了),B服务也能拿到XID,与A服务的一致。B服务是单数据源。B服务抛了异常后A服务那边正常保存了数据。有没有大佬知道是怎么回事?

展开
收起
真的很搞笑 2024-01-02 19:47:28 142 0
2 条回答
写回答
取消 提交回答
  • 根据您提供的信息,A服务调用B服务接口时,B服务抛出了异常,但A服务没有感知到。A服务是多数据源,B服务也能拿到XID并与A服务的一致,但B服务是单数据源。在B服务抛出异常后,A服务正常保存了数据。

    这种情况可能是由于以下原因导致的:

    1. 事务传播行为:在AT模式下,如果A服务和B服务之间的事务传播行为设置为REQUIRES_NEWNESTED,则当B服务抛出异常时,A服务会回滚当前事务并创建一个新的事务来执行后续操作。在这种情况下,A服务可以正常保存数据。

    2. 异常处理机制:如果A服务的异常处理机制能够捕获到B服务抛出的异常,并且进行了相应的处理(例如记录日志、重试等),那么A服务可能不会感知到异常的存在。

    3. 异步操作:如果A服务在调用B服务接口时使用了异步操作,并且将保存数据的操作放在了异步任务中执行,那么即使B服务抛出了异常,A服务的保存数据操作仍然可以正常执行。

    为了解决这个问题,您可以尝试以下方法:

    1. 检查事务传播行为:确保A服务和B服务之间的事务传播行为符合预期。如果需要保持事务一致性,可以将事务传播行为设置为REQUIREDREQUIRES_NEW;如果需要支持嵌套事务,可以将事务传播行为设置为NESTED

    2. 添加异常处理机制:在A服务的代码中添加适当的异常处理机制,以便能够捕获到B服务抛出的异常并进行相应的处理。

    3. 同步操作:如果可能的话,将保存数据的操作改为同步执行,以确保在B服务抛出异常时能够及时感知到异常的存在。

    2024-01-03 10:16:20
    赞同 展开评论 打赏
  • 面对过去,不要迷离;面对未来,不必彷徨;活在今天,你只要把自己完全展示给别人看。

    在Seata的AT模式下,如果服务A调用服务B的接口,而服务B发生异常,并且这个异常被微服务的全局异常处理机制捕获处理了,那么Seata就无法拦截到这个异常,从而无法让分布式事务生效。这是因为在微服务场景下,如果配置了统一的全局异常处理,可能会导致Seata在AT模式下无法正常回滚。

    具体到你的问题,即使B服务抛出了异常,但由于A服务是多数据源并开启了dynamic.seata=true,它可能正常保存了数据。这可能是因为A服务没有感知到B服务的异常,或者因为A服务在异常发生后仍然提交了操作。

    解决这个问题的一种方式是在全局的异常处理器中关闭分布式事务。这样即使B服务抛出异常,也不会影响A服务的事务处理。另一种可能的解决方案是将全局的异常处理器修改为只捕获非业务异常,让业务异常能够继续抛出并被Seata处理。这样可以确保在出现业务异常时,Seata可以正确地回滚事务。

    2024-01-02 22:11:48
    赞同 1 展开评论 打赏

为企业提供高效、稳定、易扩展的中间件产品。

相关电子书

更多
《Seata 1.3 新特性以及如何参与社区》 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载