事务遇到第三方API请求如何处理

一、使用场景 :

1.功能实现需多次进行数据库操作

2.方法中包含请求第三方API接口

二、第三方API使用遇到的场景

(1) 第三方API成功或失败不影响主体业务的进行,如消息推送

处理方法: 把消息推送的方法摘出来,进行异步处理,避免请求出错影响主体业务流程;

注意 : 需把异步方法抽取到另一个类中,否则@Async不生效

异步处理

image.png

(2) 第三方API与主体业务不可分割(如员工调动,员工离职相关API)

处理展示 :

① 请求API,根据API返回结果进行业务处理(进行数据库操作)

② 先进行数据库操作,再请求第三方的API

思考:①和②两种处理方式的区别?


① 请求API,根据API返回结果进行业务处理(进行数据库操作)

问题 : 如果API接口返回错误,则无需往下执行后续业务逻辑处理,直接终止

      但是,如果API请求通过, 后续业务逻辑执行一旦出错,进行回滚, API无法回滚 , 导致事务不一致
例如员工离职,已从钉钉架构中移除员工,但是数据库状态回滚为正常状态,造成数据不一致
② 先进行数据库操作,再请求第三方的API

优点:请求第三方API发生错误时,可以回滚数据库数据;

可以得出结论第①种顺序(先API,后修改库)是有致命缺陷的,这种处理方式在代码里禁止使用!

二丶遇到API如何应该如何做?

1、API请求共性

(1)、明确成功

明确成功的意思很明显,这也是我们最常用到的成功情况,当第三方给你返回200状态码或OK时,就可以是明确成功了。

可能存在的问题:请求时间过长

(2)、明确失败

明确成功的意思很明显,这也是我们最常用到的失败情况,当第三方给你返回非200状态码或OK时,就可以是明确失败了,你就可以处理回滚了。

可能存在的问题:请求时间过长

(3)、结果未知

当你请求发过去了,因为第三方处理时间过长(可能是他们服务器有问题,也可能是业务复杂),导致连接直接断开了,谁也不知道他那边是否处理完成了。

可能存在的问题:超时情况

2、API请求存在的问题

(1)、API请求超时无法处理

请求API超时,程序判定修改失败,事务回滚, 但是API方法实际还在执行,导致数据不一致。

(2)、API请求时间过长,长时间占用库问题

虽然API请求成功了,但是20s才处理完成,因为在上面我们对自己库的操作已经在事务里面了,还未提交,所以将导致我们的操作被锁定20s,当堆积的多了,就会产生问题。

3、解决方案:

方案1: 解决超时问题

如果有条件- 调用方和被调用方协调好,可以为调用方提供回调或轮询查询接口

回调:比如超级店长调用千云,千云给超级店长提供一个回调接口,返回处理结果

轮询:超级店长定时去请求千云,获取结果

这样做的好处?

通过被调用方提供的回调或轮询功能,我们能够明确的知道自己调用是否完全成功或完全失败,不会存在模棱两个的情况。保证了第三方API结果的确定性,为事务的一致性构建了前提。

这样做的缺点

这样做没有缺点,正规的程序都会提供,唯一的缺点就是不正规的可能不提供,这也就要求我们在为别人提供业务接口的时候,要根据业务的重要程度,为他人提供回调或轮询方法。

方案2:解决库占用问题

启用编程式事务,包裹住对数据库修改的操作

    // 方法上不加事务
    public SimpleMessage testA() {
        // 进行校验参数,一些查询
        Select ***

        // 开启事务,进行一些数据库修改操作
        transactionTemplate.execute(status -> {
            update ***
            update ***

            return null;
        });
        // 进行第三方API请求
        httpUtils.post***;
        return new SimpleMessage(ErrorCodeEnum.OK);
    }
使用方法

这样做的好处?

自己库的多个操作数据已经执行完成,事务也已经提交释放,且api请求不在事务中,自己的库不会被锁。

这样做的缺点

虽然库不被占用了,但是第三方请求如果失败了,事务仍然会不一致。而且还是无法解决超时问题,有可能存在超时情况,结果未知导致事务不一致。

方案3:在①和②的基础上改进

在方案②的基础上对失败的情况恢复处理(使用编程式事务)

在方案①的基础上使用 回调/轮询处理

    // 方法上不加事务
    public SimpleMessage testA() {
        // 进行校验参数,一些查询
        Select ***

        // 开启事务,进行一些数据库修改操作
        transactionTemplate.execute(status -> {
            update num = 2 where ***
            update ***

            return null;
        });
        // 进行第三方API请求
        httpUtils.post***
        // 根据API请求返回结果, 如果失败则对数据进行回退操作
        // 开启事务,进行数据恢复操作
        transactionTemplate.execute(status -> {
            update num = 1 where ***
            update ***
            return null;
        });
        return new SimpleMessage(ErrorCodeEnum.OK);
    }

提示

TransactionTemplate执行时,不论发生受检查的异常(Exception),还是不受检查的异常(RuntimeException),都会执行回滚操作,所以无需担心事务不提交问题导致的重大bug。

这样做的好处

1、防止了库被占用,且得到失败的结果后能进行手动回滚。

这样做的缺点

1.写起来比较麻烦

2.如果第三方不提供回调或轮询,还是没办法保证事务一致性,所以第三方很重要。如果第三方提供,搭配①方案使用,就是完美解决方案,如果第三方不提供,将不存在完美解决方案,也间接说明这个业务不是很重要且开发人员很拉跨。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容