分布式事务场景问题实践

今天分享微服务项目中一个容易被忽略的分布式事务问题,这是在和第三方服务对接时产生
前言:现有A B两个服务,以及第三方系统C,调用流程如下
A服务接口:

  1. 数据校验
  2. 调用B服务
  3. 根据B服务调用结果 写表

B服务对应接口:

  1. 数据校验
  2. 调用 第三方C服务(C服务这个接口也是带有 修改属性的接口)
  3. 根据结果 写表

注:自身系统A、B服务与第三方系统数据一致性如何保证暂不在本文讨论范围内


现有配置:

        自身项目服务内读超时时间为10s,而第三方服务不是很稳定,所以Feign给配置的读超时时间为60s[第三方C服务稳定时响应时间在200ms]
        结合上述流程,问题就来了,如果B服务调用第三方C服务,时间超过了10s,这个时候A服务会抛出读超时异常并回滚本地事务,但此时B服务还是在阻塞等待第三方C响应,如果C响应成功,那么最终B服务会去写表记录数据,从而导致A B服务数据不一致

这个时候有朋友就说了,使用分布式事务框架不就可以解决A B服务数据不一致的情况吗?

这里考虑两点:

  1. 已知分布式事务无论是2PC/3PC/TCC/本地消息表/MQ事务消息等等方案都会对性能造成一定影响
  2. 第三方C服务不一定会提供数据回滚接口,那这时分布式事务框架也无能为力了
  3. 业务真的需要实时一致性吗?作为业务当事人的我清楚知道这个业务并不需要保证强一致,只需要在出现异常的情况下,调用方发起重试时能保证最终成功即可

那要如何解决呢?

综合上述其实A B服务数据不一致这个场景是没有必要去使用分布式事务框架的,在B服务接口加一层验证:

  1. 数据校验
  2. 判断此数据是否已处理完毕,处理完毕则直接将A服务所需数据返回,反之则继续下面的流程
  3. 调用 第三方C服务

这样就算在异常情况下A服务超时异常了,当第二次重试请求进来时,A检测到自己未处理完毕会继续调用B服务,而B服务检测到自己已处理成功了会直接返回,A就能根据返回数据继续处理下面流程

而且我们并没有使用分布式事务框架,只是稍微改变了一下业务流程

你可能感兴趣的:(java,微服务,分布式事务)