【微服务】本地事务和远程调用的执行先后关系以及带来的风险和解决方案

前言

在做订单模块的时候,本地事务中包含了远程调用,引发一些问题,这里做一次简单的复盘。

1、问题复现

首先下完订单,调用支付服务成功,然后支付服务收到微信的回调,然后通知我支付结果
但是我的支付回调模块里面有一些业务逻辑,涉及到本地多个表的插入和修改操作,同时我把远程调用接口也都放到了我这个本地事务里。如下:

代码逻辑
	// 支付回调
	@Transactional(rollbackFor = Exception.class)
    @Override
    public RespResult<PatientPayResDTO> payCallBack(PatientPayReqDTO req) {
    	// 1、处理自己本地的逻辑
    	// 2、远程调用一些其他服务接口
    	{
			// 2.1 通知医生服务扣减库存
			// 2.2 如果医生没有库存那么进行调用支付服务退款
		}
    }
问题描述

我这个方法是一个大事务 @Transactional(rollbackFor = Exception.class),当"1、处理自己本地的逻辑完成" 之后,执行第二步的时候,调用医生服务扣减库存,如果医生没有库存,然后进行退款,此时调用支付服务进行退款。但是支付服务需要订单服务将回调的成功结果返回之后才会进行落库,如果此时发起退款,支付服务是没有完成支付成功的落库,那么就会报错。导致回滚。

代码修改之后逻辑
	// 支付回调
    @Override
    public RespResult<PatientPayResDTO> payCallBack(PatientPayReqDTO req) {
    	// 1、处理自己本地的逻辑
    	// 2、远程调用一些其他服务接口
    	{
			// 2.1 通知医生服务扣减库存
			// 2.2 如果医生没有库存那么进行调用支付服务退款
		}
    }
      @Transactional(rollbackFor = Exception.class)
	// 1、处理自己本地的逻辑

支付服务也要保证先处理自己的事务。

先完成自己本地事务,然后在进行远程调用,这样来看远程调用是否发生问题和我自身都没有关系,如果因为发出问题,导致数据不一致,我们可以采取一些兜底方式,保证数据最终一致性就好了。

后记

先保证自己,后保证他人

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值